From 06d1c0992dc66d7f2b73bfbbcbae0138c574880a Mon Sep 17 00:00:00 2001 From: Quinn Slack Date: Sun, 15 Sep 2024 16:22:19 -0700 Subject: [PATCH] reduce background network access (#5566) Skip the UpstreamHealthProviderCheck if the window is not focused, and try again when the window becomes focused again. Some users have OS firewalls that make periodic background network access annoying for users. See https://linear.app/sourcegraph/issue/CODY-3745/codys-background-periodic-network-access-causes-2fa. This check is used to gather latency information to properly measure actual latency for autocomplete. As long as the user has VS Code focused for slightly more than 10 seconds, it will still gather the necessary latency information for these calculations. Fixes https://linear.app/sourcegraph/issue/CODY-3745/codys-background-periodic-network-access-causes-2fa ## Test plan Open VS Code and check logs for the UpstreamHealthProvider call. Ensure that it does not trigger when the window is not focused, and then it triggers within 10 seconds of being focused after that. ## Changelog Suppressed Cody's background process for monitoring latency to the Sourcegraph endpoint, which was used to calculate autocomplete latency for performance tracking purposes. For users with OS firewalls that notify on background network access, this will reduce notification annoyance. --- vscode/src/services/UpstreamHealthProvider.ts | 40 ++++++++++++++++--- vscode/src/testutils/mocks.ts | 2 + 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/vscode/src/services/UpstreamHealthProvider.ts b/vscode/src/services/UpstreamHealthProvider.ts index 2f44b9518edf..4ddc79ff8338 100644 --- a/vscode/src/services/UpstreamHealthProvider.ts +++ b/vscode/src/services/UpstreamHealthProvider.ts @@ -10,7 +10,7 @@ import { wrapInActiveSpan, } from '@sourcegraph/cody-shared' import { fetch } from '@sourcegraph/cody-shared' -import type * as vscode from 'vscode' +import * as vscode from 'vscode' // We choose an interval that gives us a reasonable aggregate without causing // too many requests @@ -27,12 +27,25 @@ class UpstreamHealthProvider implements vscode.Disposable { private lastUpstreamLatency?: number private lastGatewayLatency?: number + private disposables: vscode.Disposable[] = [] + private config: Pick< ClientConfigurationWithAccessToken, 'serverEndpoint' | 'customHeaders' | 'accessToken' > | null = null private nextTimeoutId: NodeJS.Timeout | null = null + constructor() { + this.disposables.push( + vscode.window.onDidChangeWindowState(state => { + if (state.focused && this.lastMeasurementSkippedBecauseNotFocused) { + this.lastMeasurementSkippedBecauseNotFocused = false + this.enqueue(INITIAL_PING_DELAY_MS) + } + }) + ) + } + public getUpstreamLatency(): number | undefined { if (!this.config) { return undefined @@ -60,12 +73,18 @@ class UpstreamHealthProvider implements vscode.Disposable { // Enqueue the initial ping after a config change in 10 seconds. This // avoids running the test while the extension is still initializing and // competing with many other network requests. + this.enqueue(INITIAL_PING_DELAY_MS) + } + + private enqueue(delay: number): void { if (this.nextTimeoutId) { clearTimeout(this.nextTimeoutId) } - this.nextTimeoutId = setTimeout(this.measure.bind(this), INITIAL_PING_DELAY_MS) + this.nextTimeoutId = setTimeout(this.measure.bind(this), delay) } + private lastMeasurementSkippedBecauseNotFocused = false + private async measure() { if (this.nextTimeoutId) { clearTimeout(this.nextTimeoutId) @@ -76,6 +95,15 @@ class UpstreamHealthProvider implements vscode.Disposable { return } + if (!vscode.window.state.focused) { + // Skip if the window is not focused, and try again when the window becomes focused + // again. Some users have OS firewalls that make periodic background network access + // annoying for users, and this eliminates that annoyance. See + // https://linear.app/sourcegraph/issue/CODY-3745/codys-background-periodic-network-access-causes-2fa. + this.lastMeasurementSkippedBecauseNotFocused = true + return + } + if (!this.config) { throw new Error('UpstreamHealthProvider not initialized') } @@ -140,10 +168,7 @@ class UpstreamHealthProvider implements vscode.Disposable { // We don't care about errors here, we just want to measure the latency } finally { // Enqueue a new ping - if (this.nextTimeoutId) { - clearTimeout(this.nextTimeoutId) - } - this.nextTimeoutId = setTimeout(this.measure.bind(this), PING_INTERVAL_MS) + this.enqueue(PING_INTERVAL_MS) } } @@ -151,6 +176,9 @@ class UpstreamHealthProvider implements vscode.Disposable { if (this.nextTimeoutId) { clearTimeout(this.nextTimeoutId) } + for (const disposable of this.disposables) { + disposable.dispose() + } } } diff --git a/vscode/src/testutils/mocks.ts b/vscode/src/testutils/mocks.ts index 8179ee4dacbc..57d276706c74 100644 --- a/vscode/src/testutils/mocks.ts +++ b/vscode/src/testutils/mocks.ts @@ -803,6 +803,8 @@ export const vsCodeMocks = { }, onDidChangeActiveTextEditor() {}, onDidChangeTextEditorSelection() {}, + onDidChangeWindowState() {}, + state: { focused: false }, createTextEditorDecorationType: () => ({ key: 'foo', dispose: () => {},