mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2024-12-20 14:13:08 +00:00
Make the failure backoff time the same as the appUpdatePollTime
Change-type: patch Signed-off-by: Cameron Diver <cameron@balena.io>
This commit is contained in:
parent
146267b402
commit
828a0fc345
@ -64,7 +64,7 @@ createApplicationManagerRouter = (applications) ->
|
||||
module.exports = class ApplicationManager extends EventEmitter
|
||||
constructor: ({ @logger, @config, @db, @eventTracker, @deviceState }) ->
|
||||
@docker = new Docker()
|
||||
@images = new Images({ @docker, @logger, @db })
|
||||
@images = new Images({ @docker, @logger, @db, @config })
|
||||
@services = new ServiceManager({ @docker, @logger, @images, @config })
|
||||
@networks = new NetworkManager({ @docker, @logger })
|
||||
@volumes = new Volumes({ @docker, @logger })
|
||||
@ -74,6 +74,11 @@ module.exports = class ApplicationManager extends EventEmitter
|
||||
@fetchesInProgress = 0
|
||||
@_targetVolatilePerImageId = {}
|
||||
@_containerStarted = {}
|
||||
|
||||
@config.on 'change', (changedConfig) =>
|
||||
if changedConfig.appUpdatePollInterval
|
||||
@images.appUpdatePollInterval = changedConfig.appUpdatePollInterval
|
||||
|
||||
@actionExecutors = {
|
||||
stop: (step, { force = false, skipLock = false } = {}) =>
|
||||
@_lockingIfNecessary step.current.appId, { force, skipLock: skipLock or step.options?.skipLock }, =>
|
||||
@ -178,7 +183,10 @@ module.exports = class ApplicationManager extends EventEmitter
|
||||
@emit('change', data)
|
||||
|
||||
init: =>
|
||||
@images.cleanupDatabase()
|
||||
@config.get('appUpdatePollInterval')
|
||||
.then (interval) =>
|
||||
@images.appUpdatePollInterval = interval
|
||||
@images.cleanupDatabase()
|
||||
.then =>
|
||||
@localModeManager.init()
|
||||
.then =>
|
||||
|
@ -4,6 +4,7 @@ import { EventEmitter } from 'events';
|
||||
import * as _ from 'lodash';
|
||||
import StrictEventEmitter from 'strict-event-emitter-types';
|
||||
|
||||
import Config from '../config';
|
||||
import Database from '../db';
|
||||
import * as constants from '../lib/constants';
|
||||
import {
|
||||
@ -27,6 +28,7 @@ interface ImageConstructOpts {
|
||||
docker: DockerUtils;
|
||||
logger: Logger;
|
||||
db: Database;
|
||||
config: Config;
|
||||
}
|
||||
|
||||
interface FetchProgressEvent {
|
||||
@ -65,6 +67,8 @@ export class Images extends (EventEmitter as {
|
||||
private logger: Logger;
|
||||
private db: Database;
|
||||
|
||||
public appUpdatePollInterval: number;
|
||||
|
||||
private imageFetchFailures: Dictionary<number> = {};
|
||||
private imageFetchLastFailureTime: Dictionary<
|
||||
ReturnType<typeof process.hrtime>
|
||||
@ -92,7 +96,7 @@ export class Images extends (EventEmitter as {
|
||||
// engine, and ensure that we wait a bit lnger
|
||||
const minDelay = Math.min(
|
||||
2 ** this.imageFetchFailures[image.name] * constants.backoffIncrement,
|
||||
constants.maxBackoffTime,
|
||||
this.appUpdatePollInterval,
|
||||
);
|
||||
const timeSinceLastError = process.hrtime(
|
||||
this.imageFetchLastFailureTime[image.name],
|
||||
|
@ -138,11 +138,11 @@ module.exports = class DeviceState extends EventEmitter
|
||||
@applications.on('change', @reportCurrentState)
|
||||
|
||||
healthcheck: =>
|
||||
@config.getMany([ 'appUpdatePollInterval', 'unmanaged' ])
|
||||
@config.getMany([ 'unmanaged' ])
|
||||
.then (conf) =>
|
||||
cycleTime = process.hrtime(@lastApplyStart)
|
||||
cycleTimeMs = cycleTime[0] * 1000 + cycleTime[1] / 1e6
|
||||
cycleTimeWithinInterval = cycleTimeMs - @applications.timeSpentFetching < 2 * conf.appUpdatePollInterval
|
||||
cycleTimeWithinInterval = cycleTimeMs - @applications.timeSpentFetching < 2 * @maxPollTime
|
||||
applyTargetHealthy = conf.unmanaged or !@applyInProgress or @applications.fetchesInProgress > 0 or cycleTimeWithinInterval
|
||||
return applyTargetHealthy
|
||||
|
||||
@ -249,13 +249,16 @@ module.exports = class DeviceState extends EventEmitter
|
||||
@logger.enable(changedConfig.loggingEnabled)
|
||||
if changedConfig.apiSecret?
|
||||
@reportCurrentState(api_secret: changedConfig.apiSecret)
|
||||
if changedConfig.appUpdatePollInterval?
|
||||
@maxPollTime = changedConfig.appUpdatePollInterval
|
||||
|
||||
@config.getMany([
|
||||
'initialConfigSaved', 'listenPort', 'apiSecret', 'osVersion', 'osVariant',
|
||||
'version', 'provisioned', 'apiEndpoint', 'connectivityCheckEnabled', 'legacyAppsPresent',
|
||||
'targetStateSet', 'unmanaged'
|
||||
'targetStateSet', 'unmanaged', 'appUpdatePollInterval'
|
||||
])
|
||||
.then (conf) =>
|
||||
@maxPollTime = conf.appUpdatePollInterval
|
||||
@applications.init()
|
||||
.then =>
|
||||
if !conf.initialConfigSaved
|
||||
@ -570,7 +573,7 @@ module.exports = class DeviceState extends EventEmitter
|
||||
if @scheduledApply?
|
||||
console.log("Updating failed, but there's another update scheduled immediately: ", err)
|
||||
else
|
||||
delay = Math.min((2 ** @failedUpdates) * constants.backoffIncrement, constants.maxBackoffTime)
|
||||
delay = Math.min((2 ** @failedUpdates) * constants.backoffIncrement, @maxPollTime)
|
||||
# If there was an error then schedule another attempt briefly in the future.
|
||||
console.log('Scheduling another update attempt due to failure: ', delay, err)
|
||||
@triggerApplyTarget({ force, delay, initial })
|
||||
|
@ -53,8 +53,6 @@ const constants = {
|
||||
// Use this failure multiplied by 2**Number of failures to increase
|
||||
// the backoff on subsequent failures
|
||||
backoffIncrement: 500,
|
||||
// The maximum time to backoff on repeated failure
|
||||
maxBackoffTime: 30000,
|
||||
};
|
||||
|
||||
if (process.env.DOCKER_HOST == null) {
|
||||
|
Loading…
Reference in New Issue
Block a user