Skip to content

Commit

Permalink
reduce background network access (#5566)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sqs authored Sep 15, 2024
1 parent c758d5a commit 06d1c09
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 6 deletions.
40 changes: 34 additions & 6 deletions vscode/src/services/UpstreamHealthProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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')
}
Expand Down Expand Up @@ -140,17 +168,17 @@ 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)
}
}

public dispose(): void {
if (this.nextTimeoutId) {
clearTimeout(this.nextTimeoutId)
}
for (const disposable of this.disposables) {
disposable.dispose()
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions vscode/src/testutils/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,8 @@ export const vsCodeMocks = {
},
onDidChangeActiveTextEditor() {},
onDidChangeTextEditorSelection() {},
onDidChangeWindowState() {},
state: { focused: false },
createTextEditorDecorationType: () => ({
key: 'foo',
dispose: () => {},
Expand Down

0 comments on commit 06d1c09

Please sign in to comment.