Auto-retry transient update errors once
This commit is contained in:
parent
f55abcbdc8
commit
1f693be9fc
1 changed files with 39 additions and 4 deletions
|
@ -111,6 +111,10 @@ enum CheckType {
|
||||||
ForceDownload = 'ForceDownload',
|
ForceDownload = 'ForceDownload',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MAX_AUTO_RETRY_ATTEMPTS = 1;
|
||||||
|
|
||||||
|
const AUTO_RETRY_DELAY = durations.DAY;
|
||||||
|
|
||||||
export abstract class Updater {
|
export abstract class Updater {
|
||||||
protected fileName: string | undefined;
|
protected fileName: string | undefined;
|
||||||
|
|
||||||
|
@ -139,6 +143,10 @@ export abstract class Updater {
|
||||||
|
|
||||||
private readonly canRunSilently: () => boolean;
|
private readonly canRunSilently: () => boolean;
|
||||||
|
|
||||||
|
private autoRetryAttempts = 0;
|
||||||
|
|
||||||
|
private autoRetryAfter: number | undefined;
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
settingsChannel,
|
settingsChannel,
|
||||||
logger,
|
logger,
|
||||||
|
@ -268,7 +276,7 @@ export abstract class Updater {
|
||||||
);
|
);
|
||||||
const timeoutMs = selectedPollTime - now;
|
const timeoutMs = selectedPollTime - now;
|
||||||
|
|
||||||
this.logger.info(`updater/start: polling in ${timeoutMs}ms`);
|
this.logger.info(`updater/schedulePoll: polling in ${timeoutMs}ms`);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
drop(this.safePoll());
|
drop(this.safePoll());
|
||||||
|
@ -277,10 +285,17 @@ export abstract class Updater {
|
||||||
|
|
||||||
private async safePoll(): Promise<void> {
|
private async safePoll(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
this.logger.info('updater/start: polling now');
|
if (this.autoRetryAfter != null && Date.now() < this.autoRetryAfter) {
|
||||||
|
this.logger.info(
|
||||||
|
`updater/safePoll: not polling until ${this.autoRetryAfter}`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.info('updater/safePoll: polling now');
|
||||||
await this.checkForUpdatesMaybeInstall(CheckType.Normal);
|
await this.checkForUpdatesMaybeInstall(CheckType.Normal);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(`updater/start: ${Errors.toLogFormat(error)}`);
|
this.logger.error(`updater/safePoll: ${Errors.toLogFormat(error)}`);
|
||||||
} finally {
|
} finally {
|
||||||
this.schedulePoll();
|
this.schedulePoll();
|
||||||
}
|
}
|
||||||
|
@ -323,9 +338,27 @@ export abstract class Updater {
|
||||||
// Restore state in case of download error
|
// Restore state in case of download error
|
||||||
this.version = oldVersion;
|
this.version = oldVersion;
|
||||||
|
|
||||||
|
if (
|
||||||
|
mode === DownloadMode.Automatic &&
|
||||||
|
this.autoRetryAttempts < MAX_AUTO_RETRY_ATTEMPTS
|
||||||
|
) {
|
||||||
|
this.autoRetryAttempts += 1;
|
||||||
|
this.autoRetryAfter = Date.now() + AUTO_RETRY_DELAY;
|
||||||
|
logger.warn(
|
||||||
|
'downloadAndInstall: transient error ' +
|
||||||
|
`${Errors.toLogFormat(error)}, ` +
|
||||||
|
`attempts=${this.autoRetryAttempts}, ` +
|
||||||
|
`retryAfter=${this.autoRetryAfter}`
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.autoRetryAttempts = 0;
|
||||||
|
this.autoRetryAfter = undefined;
|
||||||
|
|
||||||
if (!downloadResult) {
|
if (!downloadResult) {
|
||||||
logger.warn('downloadAndInstall: no update was downloaded');
|
logger.warn('downloadAndInstall: no update was downloaded');
|
||||||
strictAssert(
|
strictAssert(
|
||||||
|
@ -389,7 +422,9 @@ export abstract class Updater {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`downloadAndInstall: ${Errors.toLogFormat(error)}`);
|
logger.error(
|
||||||
|
`downloadAndInstall: fatal error ${Errors.toLogFormat(error)}`
|
||||||
|
);
|
||||||
this.markCannotUpdate(error);
|
this.markCannotUpdate(error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue