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:
Pablo Carranza Vélez 2019-04-03 10:06:21 -07:00 committed by GitHub
commit 7be35d783e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 64 additions and 14 deletions

View File

@ -363,7 +363,7 @@ export class APIBinder {
'Trying to start poll without initializing API client',
);
}
this.pollTargetState();
this.pollTargetState(true);
return null;
});
}
@ -568,19 +568,27 @@ 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'],
);
try {
await this.getAndSetTargetState(false);
this.targetStateFetchErrors = 0;
} catch (e) {
pollInterval = Math.min(
pollInterval,
15000 * 2 ** this.targetStateFetchErrors,
);
++this.targetStateFetchErrors;
// 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(
appUpdatePollInterval,
15000 * 2 ** this.targetStateFetchErrors,
);
++this.targetStateFetchErrors;
}
}
await Bluebird.delay(pollInterval);
@ -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);
}
res.sendStatus(204);
});
return router;

View File

@ -66,6 +66,10 @@ export const schemaTypes = {
type: PermissiveNumber,
default: 60000,
},
instantUpdates: {
type: PermissiveBoolean,
default: true,
},
mixpanelToken: {
type: t.string,
default: constants.defaultMixpanelToken,

View File

@ -185,6 +185,11 @@ export const schema = {
mutable: true,
removeIfNull: false,
},
instantUpdates: {
source: 'db',
mutable: true,
removeIfNull: false,
},
};
export type Schema = typeof schema;

View File

@ -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',

View File

@ -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'

View File

@ -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',
})