Skip to content

Commit

Permalink
gopls/internal/cache: join concurrent package batch operations
Browse files Browse the repository at this point in the history
One of the unsolved problems of the gopls scalability redesign described
at https://go.dev/blog/gopls-scalability is that concurrent type
checking operations may perform redundant work. While we avoided
redundancy within the context of *one* operation, by encapsulating the
type checking batch, it is possible that there will be logically
distinct operations occurring concurrently, such as computing
diagnostics and autocompletion. These operations could not share type
information, as they were operating within distinct type checking
"realms" (recall that go/types relies on the canonicalization of
imports).

This CL addresses that problem by refactoring the type checking batch
such that it can join two distinct operations into a shared state. The
typeCheckBatch becomes a queryable entity, coordinating work across
ongoing package graph traversals.

This required surprisingly little change to the typeCheckBatch itself,
which already abstracted the notion of a package traversal. Rather, the
key missing component was a future cache implementation that was (1)
retryable and (2) transient, in the sense that computed values were
discarded after use. The bulk of this change is the implementation and
testing of such a cache.

Some elements of the refactoring remain awkward:

- packageHandles are collected and merged into a shared map, because
  they must still be computed in large batches for efficiency.
- the shared importGraph remains a clumsy optimization, requiring subtle
  logic to pre-build a shared import graph.

My intuition is that both of these problems have an elegant solution,
but this work is left for a subsequent CL.

In addition to reducing CPU across the board, due to less redundancy in
the existing diagnostic pass, this CL will facilitate the following
additions to gopls:

- Pull-based diagnostics (golang/go#53275): now that diagnostic
  operations are naturally joined, there is less need for gopls to
  manage the scheduling of the diagnostic pass.
- Improvements to loading behavior (golang/go#68002): being able to
  handle requests asynchronously allows completion requests to
  potentially be handled using stale metadata.

Updates golang/go#53275
Updates golang/go#68002

Change-Id: Ib228cdcce2c4b6f616d6ba5b0abeb40e87f449be
Reviewed-on: https://go-review.googlesource.com/c/tools/+/611843
Reviewed-by: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
  • Loading branch information
findleyr committed Sep 25, 2024
1 parent 34638fc commit 83326b7
Show file tree
Hide file tree
Showing 5 changed files with 504 additions and 200 deletions.
Loading

0 comments on commit 83326b7

Please sign in to comment.