From fe27910221cfc2be3900e97e3680a69e2835faf6 Mon Sep 17 00:00:00 2001 From: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com> Date: Wed, 14 Feb 2024 10:27:31 -0800 Subject: [PATCH] Jitter updater poll timeout --- ts/updater/common.ts | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/ts/updater/common.ts b/ts/updater/common.ts index 7e880d7030e0..2c3090d65f5b 100644 --- a/ts/updater/common.ts +++ b/ts/updater/common.ts @@ -25,6 +25,7 @@ import { DialogType } from '../types/Dialogs'; import * as Errors from '../types/errors'; import { isAlpha, isBeta, isStaging } from '../util/version'; import { strictAssert } from '../util/assert'; +import { drop } from '../util/drop'; import * as packageJson from '../../package.json'; import { @@ -46,7 +47,7 @@ import { isValidPreparedData as isValidDifferentialData, } from './differential'; -const INTERVAL = 30 * durations.MINUTE; +const POLL_INTERVAL = 30 * durations.MINUTE; type JSONVendorSchema = { minOSVersion?: string; @@ -148,13 +149,7 @@ export abstract class Updater { public async start(): Promise { this.logger.info('updater/start: starting checks...'); - setInterval(async () => { - try { - await this.checkForUpdatesMaybeInstall(); - } catch (error) { - this.logger.error(`updater/start: ${Errors.toLogFormat(error)}`); - } - }, INTERVAL); + this.schedulePoll(); await this.deletePreviousInstallers(); await this.checkForUpdatesMaybeInstall(); @@ -216,6 +211,33 @@ export abstract class Updater { // Private methods // + private schedulePoll(): void { + const now = Date.now(); + + const earliestPollTime = now - (now % POLL_INTERVAL) + POLL_INTERVAL; + const selectedPollTime = Math.round( + earliestPollTime + Math.random() * POLL_INTERVAL + ); + const timeoutMs = selectedPollTime - now; + + this.logger.info(`updater/start: polling in ${timeoutMs}ms`); + + setTimeout(() => { + drop(this.safePoll()); + }, timeoutMs); + } + + private async safePoll(): Promise { + try { + this.logger.info('updater/start: polling now'); + await this.checkForUpdatesMaybeInstall(); + } catch (error) { + this.logger.error(`updater/start: ${Errors.toLogFormat(error)}`); + } finally { + this.schedulePoll(); + } + } + private async downloadAndInstall( updateInfo: UpdateInformationType, mode: DownloadMode