mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-01-19 11:16:34 +00:00
Merge pull request #934 from balena-io/polling-jitter
Add a random jitter to target state polls, and a config var to ignore…
This commit is contained in:
commit
7be35d783e
@ -363,7 +363,7 @@ export class APIBinder {
|
||||
'Trying to start poll without initializing API client',
|
||||
);
|
||||
}
|
||||
this.pollTargetState();
|
||||
this.pollTargetState(true);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
@ -568,20 +568,28 @@ export class APIBinder {
|
||||
});
|
||||
}
|
||||
|
||||
private async pollTargetState(): Promise<void> {
|
||||
private async pollTargetState(isInitialCall: boolean = false): Promise<void> {
|
||||
// TODO: Remove the checkInt here with the config changes
|
||||
let pollInterval = await this.config.get('appUpdatePollInterval');
|
||||
const { appUpdatePollInterval, instantUpdates } = await this.config.getMany(
|
||||
['appUpdatePollInterval', 'instantUpdates'],
|
||||
);
|
||||
|
||||
// We add jitter to the poll interval so that it's between 0.5 and 1.5 times
|
||||
// the configured interval
|
||||
let pollInterval = (0.5 + Math.random()) * appUpdatePollInterval;
|
||||
|
||||
if (instantUpdates || !isInitialCall) {
|
||||
try {
|
||||
await this.getAndSetTargetState(false);
|
||||
this.targetStateFetchErrors = 0;
|
||||
} catch (e) {
|
||||
pollInterval = Math.min(
|
||||
pollInterval,
|
||||
appUpdatePollInterval,
|
||||
15000 * 2 ** this.targetStateFetchErrors,
|
||||
);
|
||||
++this.targetStateFetchErrors;
|
||||
}
|
||||
}
|
||||
|
||||
await Bluebird.delay(pollInterval);
|
||||
await this.pollTargetState();
|
||||
@ -912,9 +920,33 @@ export class APIBinder {
|
||||
router.post('/v1/update', (req, res) => {
|
||||
apiBinder.eventTracker.track('Update notification');
|
||||
if (apiBinder.readyForUpdates) {
|
||||
apiBinder.getAndSetTargetState(req.body.force, true).catch(_.noop);
|
||||
}
|
||||
this.config
|
||||
.get('instantUpdates')
|
||||
.then(instantUpdates => {
|
||||
if (instantUpdates) {
|
||||
apiBinder
|
||||
.getAndSetTargetState(req.body.force, true)
|
||||
.catch(_.noop);
|
||||
res.sendStatus(204);
|
||||
} else {
|
||||
console.log(
|
||||
'Ignoring update notification because instant updates are disabled',
|
||||
);
|
||||
res.sendStatus(202);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
const msg =
|
||||
err.message != null
|
||||
? err.message
|
||||
: err != null
|
||||
? err
|
||||
: 'Unknown error';
|
||||
res.status(503).send(msg);
|
||||
});
|
||||
} else {
|
||||
res.sendStatus(202);
|
||||
}
|
||||
});
|
||||
|
||||
return router;
|
||||
|
@ -66,6 +66,10 @@ export const schemaTypes = {
|
||||
type: PermissiveNumber,
|
||||
default: 60000,
|
||||
},
|
||||
instantUpdates: {
|
||||
type: PermissiveBoolean,
|
||||
default: true,
|
||||
},
|
||||
mixpanelToken: {
|
||||
type: t.string,
|
||||
default: constants.defaultMixpanelToken,
|
||||
|
@ -185,6 +185,11 @@ export const schema = {
|
||||
mutable: true,
|
||||
removeIfNull: false,
|
||||
},
|
||||
instantUpdates: {
|
||||
source: 'db',
|
||||
mutable: true,
|
||||
removeIfNull: false,
|
||||
},
|
||||
};
|
||||
|
||||
export type Schema = typeof schema;
|
||||
|
@ -68,6 +68,11 @@ export class DeviceConfig {
|
||||
varType: 'int',
|
||||
defaultValue: '60000',
|
||||
},
|
||||
instantUpdates: {
|
||||
envVarName: 'SUPERVISOR_INSTANT_UPDATE_TRIGGER',
|
||||
varType: 'bool',
|
||||
defaultValue: 'true',
|
||||
},
|
||||
localMode: {
|
||||
envVarName: 'SUPERVISOR_LOCAL_MODE',
|
||||
varType: 'bool',
|
||||
|
@ -21,6 +21,7 @@ mockedInitialConfig = {
|
||||
'RESIN_SUPERVISOR_DELTA_RETRY_COUNT': '30'
|
||||
'RESIN_SUPERVISOR_DELTA_RETRY_INTERVAL': '10000'
|
||||
'RESIN_SUPERVISOR_DELTA_VERSION': '2'
|
||||
'RESIN_SUPERVISOR_INSTANT_UPDATE_TRIGGER': 'true'
|
||||
'RESIN_SUPERVISOR_LOCAL_MODE': 'false'
|
||||
'RESIN_SUPERVISOR_LOG_CONTROL': 'true'
|
||||
'RESIN_SUPERVISOR_OVERRIDE_LOCK': 'false'
|
||||
@ -40,6 +41,7 @@ testTarget1 = {
|
||||
'SUPERVISOR_DELTA_RETRY_COUNT': '30'
|
||||
'SUPERVISOR_DELTA_RETRY_INTERVAL': '10000'
|
||||
'SUPERVISOR_DELTA_VERSION': '2'
|
||||
'SUPERVISOR_INSTANT_UPDATE_TRIGGER': 'true'
|
||||
'SUPERVISOR_LOCAL_MODE': 'false'
|
||||
'SUPERVISOR_LOG_CONTROL': 'true'
|
||||
'SUPERVISOR_OVERRIDE_LOCK': 'false'
|
||||
@ -122,6 +124,7 @@ testTargetWithDefaults2 = {
|
||||
'SUPERVISOR_DELTA_RETRY_COUNT': '30'
|
||||
'SUPERVISOR_DELTA_RETRY_INTERVAL': '10000'
|
||||
'SUPERVISOR_DELTA_VERSION': '2'
|
||||
'SUPERVISOR_INSTANT_UPDATE_TRIGGER': 'true'
|
||||
'SUPERVISOR_LOCAL_MODE': 'false'
|
||||
'SUPERVISOR_LOG_CONTROL': 'true'
|
||||
'SUPERVISOR_OVERRIDE_LOCK': 'false'
|
||||
|
@ -178,6 +178,7 @@ describe 'DeviceConfig', ->
|
||||
SUPERVISOR_DELTA_RETRY_COUNT: '30',
|
||||
SUPERVISOR_DELTA_RETRY_INTERVAL: '10000',
|
||||
SUPERVISOR_DELTA_VERSION: '2',
|
||||
SUPERVISOR_INSTANT_UPDATE_TRIGGER: 'true',
|
||||
SUPERVISOR_OVERRIDE_LOCK: 'false',
|
||||
SUPERVISOR_PERSISTENT_LOGGING: 'false',
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user