diff --git a/src/view/reviewManager.ts b/src/view/reviewManager.ts index 38bc2b3341..c3ff30c921 100644 --- a/src/view/reviewManager.ts +++ b/src/view/reviewManager.ts @@ -145,6 +145,15 @@ export class ReviewManager extends Disposable { this.updateState(true); } this.pollForStateChange(); + this._register(vscode.window.onDidChangeWindowState(state => { + if (state.focused && !this._pollHandle) { + // Polling was skipped because the window was not focused. + // Schedule a poll with a randomized delay (jitter) so that in + // multi-repo setups all ReviewManagers don't poll at the same time. + const jitter = 15_000 + Math.floor(Math.random() * 45_000); // 15-60s + this._pollHandle = setTimeout(() => this.doPoll(), jitter); + } + })); this._register(toDisposable(() => { if (this._pollHandle) { clearTimeout(this._pollHandle); @@ -229,23 +238,35 @@ export class ReviewManager extends Disposable { } private pollForStateChange() { - this._pollHandle = setTimeout(async () => { - if (this.isDisposed) { - return; + if (this._pollHandle) { + clearTimeout(this._pollHandle); + } + this._pollHandle = setTimeout(() => this.doPoll(), 1000 * 60 * 5); + } + + private async doPoll() { + if (this.isDisposed) { + return; + } + this._pollHandle = undefined; + if (!vscode.window.state.focused) { + // Skip polling while the window is not focused. Polling will resume + // immediately when the window regains focus (see onDidChangeWindowState). + Logger.appendLine('Skipping poll: window is not focused', this.id); + return; + } + Logger.appendLine('Polling for state change...', this.id); + try { + if (!this._validateStatusInProgress && !this._folderRepoManager.activePullRequest) { + await this.updateState(); } - Logger.appendLine('Polling for state change...', this.id); - try { - if (!this._validateStatusInProgress && !this._folderRepoManager.activePullRequest) { - await this.updateState(); - } - } catch (e) { - Logger.warn(`Polling for state change failed: ${formatError(e)}`, this.id); - } finally { - if (!this.isDisposed) { - this.pollForStateChange(); - } + } catch (e) { + Logger.warn(`Polling for state change failed: ${formatError(e)}`, this.id); + } finally { + if (!this.isDisposed) { + this.pollForStateChange(); } - }, 1000 * 60 * 5); + } } private async updateBaseBranchMetadata(oldHead: Branch, newHead: Branch) {