Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Autocomplete: Enable keepalive agent for Node #868

Merged
merged 14 commits into from
Sep 1, 2023

Conversation

philipp-spiess
Copy link
Contributor

@philipp-spiess philipp-spiess commented Aug 30, 2023

We found another small way to improve overall latencies: Making sure we keep the TCP connection alive and reducing the need for subsequent SSL/TLS handshakes.

In Node, reusing TCP connections is not the default behavior (like it is for example on our Go backends). To fix this, we have to make sure we create a custom network agent that is configured to keep connections allive.

Since this is Node only, we are using a mutable ref objects to not run any of those code paths on the web branches.

c.f. https://sourcegraph.slack.com/archives/C05497E9MDW/p1693387804620389

Test plan

Tested using the local completion CLI script

We found about a 5% latency improvement:

image

@philipp-spiess philipp-spiess marked this pull request as draft August 30, 2023 17:28
@philipp-spiess philipp-spiess changed the title WIP Autocomplete: Enable keepalive agent for Node Autocomplete: Enable keepalive agent for Node Aug 31, 2023
@philipp-spiess philipp-spiess requested a review from a team August 31, 2023 10:06
@philipp-spiess philipp-spiess self-assigned this Aug 31, 2023
@@ -21,6 +22,8 @@ import { getRgPath } from './rg'
* (Node.js/Electron).
*/
export function activate(context: vscode.ExtensionContext): ExtensionApi {
initializeNetworkAgent()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@olafurpg Is this method being run when the agent is starting up? :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep looks like the Agent calls this function: https://sourcegraph.com/github.com/sourcegraph/cody@ps/autocomplete-keepalive/-/blob/agent/src/agent.ts?L22

free wins for agent again 💅

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the ping. Yes, the agent tries to be as invisible as possible 🙈

export function fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {
return isomorphicFetch(input, {
...init,
agent: agent.current,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cbart This pattern should also help you unblock #836

@philipp-spiess philipp-spiess marked this pull request as ready for review August 31, 2023 10:08
@umpox
Copy link
Contributor

umpox commented Aug 31, 2023

Out of curiosity, what is your "http.proxySupport" value in VS Code? I looked into this for a moment yesterday but noticed that VS Code patches over the agent for the default proxySupport value (override). Related issue: microsoft/vscode#173861

@philipp-spiess
Copy link
Contributor Author

@umpox Oh, interesting. Yeah I remember that I have had to deal with that before for the old SG VS Code extension. I have set it to "http.proxySupport": "off", right now and it did seem to try and use the agent (I validated that by returning {} and it throwed). Let me check what happens with the default values 🤔

@philipp-spiess
Copy link
Contributor Author

@umpox Yeah this is not doing anything for the default value. uh noes. I wonder if we can monkeypatch it somehow.

@philipp-spiess
Copy link
Contributor Author

@umpox yeah i think there's nothing we can do when the default option is set. So this change will only have an impact for users that either have "http.proxySupport": "off" set or are in our controlled environments like Agent.

Wow this is frustrating.

@philipp-spiess
Copy link
Contributor Author

I found a way 😐

Copy link
Contributor

@umpox umpox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Member

@valerybugakov valerybugakov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested it locally. Great find, @philipp-spiess!


import { agent } from './fetch'

const nodeModules = '_VSCODE_NODE_MODULES'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This field is marked as deprecated, but we're safe since errors are ignored, and we won't get latency improvements in the worst-case scenario.

vscode/src/fetch.node.ts Show resolved Hide resolved
Comment on lines +3 to +7
/**
* By hard-requiring isomorphic-fetch, we ensure that even in newer Node environments that include
* `fetch` by default, we still use the `node-fetch` polyfill and have access to the networking code
*/
import isomorphicFetch from 'isomorphic-fetch'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By networking code, do you mean access to RequestInit['agent']? If VS Code migrates to the node.js version with native fetch, can we migrate to the new HTTP stack alternative (Dispatcher)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@valerybugakov Yeah I found that relying on the polyfilled global fetch, node-fetch was used in VS Code (older Node.js version) but the native fetch was used on Node 20 (CLI). By requiering fetch here, it would always use node-fetch in Node environment.s

Wow I wasn't aware of undici this is amazing. I’m glad we see some improvements there. We'll have to still use some polyfills though because this code can also run inside a browser 🦭

vscode/src/fetch.node.ts Show resolved Hide resolved
vscode/src/fetch.ts Outdated Show resolved Hide resolved
vscode/src/completions/client.ts Outdated Show resolved Hide resolved
philipp-spiess and others added 2 commits September 1, 2023 11:29
Co-authored-by: Valery Bugakov <skymk1@gmail.com>
Co-authored-by: Valery Bugakov <skymk1@gmail.com>
@philipp-spiess philipp-spiess merged commit 672b649 into main Sep 1, 2023
8 of 9 checks passed
@philipp-spiess philipp-spiess deleted the ps/autocomplete-keepalive branch September 1, 2023 10:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants