-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
Add service-worker based cancellation (and maybe RPC) for use in vscode.dev by synchronous LSs #148967
Comments
@DanielRosenwasser @jrieken and I had a discussion about this and since we are enabling |
Is there a tracking issue for that implementation somewhere to follow? |
No, but the implementation will very likely be in https://github.com/microsoft/vscode-wasi |
Just to give a TL;DR - this is something that both TypeScript and Pylance need in order to prevent hangs from long-running operations on the web. For example, let's say a user types (which implicitly requests completions), and then keeps typing (which requests completions again). We can't detect that its results aren't needed, so the request has to be served up before the next completions request can even start. So if that request would usually take 200ms, there's a risk of 400ms completions and maybe some noisy UI This gets exacerbated on the length of the operation. Find-all-refs, for instance, can take more than a few seconds. vscode.dev should feel lightweight, but each of these operations can make things feel choppy. |
Both TypeScript and Pylance are synchronous monstrosities, which on the desktop rely on synchronous filesystem accesses to check for cancellation of requests (as opposed to the more traditional RPC based cancel messages). In the browser, however, there's no synchronous filesystem at all, so both language servers opt to not implement cancellation at all.
There are only two synchronous things a web worker can do receive data:
SharedArrayBuffer
. My understanding is that this is currently blocked due to the impact of the headers that would need to be applied to various CDNs and such.XMLHttpRequest
. This is already used by TypeScript and Pylance to pull type declarations / type stubs in as needed.The requests that a web worker makes with a synchronous
XMLHttpRequest
are visible to the site's service worker. Normally a service worker is used for caching of requests (for performance and offline support), but there's nothing stopping a service worker from answering requests without actually hitting the network.This fact leads to an opportunity to create an API that to a web worker appears to be synchronous, but can be implemented asynchronously elsewhere.
I have a demo I presented to the TS team, the Pylance team, and @mjbvz: https://jakebailey.github.io/sw-cancellation-poc/
This demo works by having the service worker intercept requests to paths like
/@cancellation@/
, and then check to see if the main page (in this case, the client side of the RPC) has triggered cancellation or not. The main page can communicate to the service worker in any way it likes (HTTP orpostMessage
); all that matters is that the web worker can check this synchronously.Cancellation is the main focus here; the data is ephemeral and best effort. But, this same method can be used to provide synchronous access to potentially any API, including file system access, which may simplify the implementation of VFS support in TypeScript and Pylance, both of which cannot do asynchronous accesses. My demo page also includes that as well.
I propose to add something like this to vscode.dev/github.dev's service worker; an extension cannot add its own service worker, so without
SharedArrayBuffer
, this is the only method available for TS and Python to get cancellation, and must be implemented in VS Code itself.cc @DanielRosenwasser @RyanCavanaugh @heejaechang @bschnurr @debonte @gramster @erictraut @luabud
The text was updated successfully, but these errors were encountered: