You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While gopls performs some background operations such as producing diagnostics asynchronously, it has never handled jsonrpc2 requests asynchronously. In the past, this didn't matter much, because the bulk of request handling was type checking, and type checked open packages are memoized, so typically the first request would be slow, but subsequent requests would be fast.
However, there have always been areas where true concurrent request handling would be helpful, and recently we've added a couple more:
Not every request requires type information. For example, DocumentSymbols and WorkspaceSymbols use only syntax (and perhaps a simplified version of SemanticTokens could as well).
Some executeCommand requests are long running, and yet want to return a result (e.g. gopls.vulncheck). We've been working around this with an ad-hoc callback to fetch the results. This is important for building more complicated client logic on top of gopls, such as we want to do for refactoring.
We should make gopls concurrent. In order for this to work, we need jsonrpc2 APIs that delegate control over concurrent handling to the core of gopls (not the RPC layer), because gopls needs to start handling the request (acquiring a Snapshot) before the next request may proceed, in order to preserve the logical ordering of requests.
Eventually, we should do this with the new jsonrpc2_v2 library, which has better APIs for handler binding, and will result in a cleaner overall result. However, @adonovan and I were discussing, and he pointed out that we can use a trick similar to t.Parallel to "release" requests, allowing concurrency to be implemented with minimal API change.
The text was updated successfully, but these errors were encountered:
gopherbot
added
Tools
This label describes issues relating to any tools in the x/tools repository.
gopls
Issues related to the Go language server, gopls.
labels
Oct 18, 2024
As described in golang/go#69937, we need a mechanism that allows for
concurrent request handling in gopls. However, this cannot be
implemented entirely within the jsonrpc2 layer, because we need gopls to
observe requests in the order they arrive, so it can handle them with
the correct logical state.
This CL adds such a concurrency mechanism using a trick similar to
t.Parallel. Specifically, a new jsonrpc2.Async method is introduced
which, when invoked on the request context, signals the
jsonrpc2.AsyncHandler to start handling the next request.
Initially, we use this new mechanism within gopls to allow certain
long-running commands to execute asynchronously, once they have acquired
a cache.Snapshot representing the current logical state. This solves a
long-standing awkwardness in the govulncheck integration, which required
an additional gopls.fetch_vulncheck_result command to fetch an
asynchronous result.
This enables some code deletion and simplification, though we could
simplify further. Notably, change the code_action subcommand to
eliminate the progress handler registration, since we don't need
progress to know when a command is complete. Instead, use -v as a signal
to log progress reports to stderr.
Fixesgolang/go#69937
Change-Id: I8736a445084cfa093f37c479d419294d5a1acbce
Reviewed-on: https://go-review.googlesource.com/c/tools/+/621055
Reviewed-by: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
While gopls performs some background operations such as producing diagnostics asynchronously, it has never handled jsonrpc2 requests asynchronously. In the past, this didn't matter much, because the bulk of request handling was type checking, and type checked open packages are memoized, so typically the first request would be slow, but subsequent requests would be fast.
However, there have always been areas where true concurrent request handling would be helpful, and recently we've added a couple more:
We should make gopls concurrent. In order for this to work, we need jsonrpc2 APIs that delegate control over concurrent handling to the core of gopls (not the RPC layer), because gopls needs to start handling the request (acquiring a Snapshot) before the next request may proceed, in order to preserve the logical ordering of requests.
Eventually, we should do this with the new jsonrpc2_v2 library, which has better APIs for handler binding, and will result in a cleaner overall result. However, @adonovan and I were discussing, and he pointed out that we can use a trick similar to t.Parallel to "release" requests, allowing concurrency to be implemented with minimal API change.
The text was updated successfully, but these errors were encountered: