Skip to content

Instantly share code, notes, and snippets.

@rma-stripe
Last active October 21, 2025 22:57
Show Gist options
  • Select an option

  • Save rma-stripe/c9c5573025209389678af3a9755137e6 to your computer and use it in GitHub Desktop.

Select an option

Save rma-stripe/c9c5573025209389678af3a9755137e6 to your computer and use it in GitHub Desktop.
diff --git a/internal/cache/snapshot.go b/internal/cache/snapshot.go
index d575ae63b613..6278d4df5fa7 100644
--- a/internal/cache/snapshot.go
+++ b/internal/cache/snapshot.go
@@ -23,6 +23,7 @@ import (
"strconv"
"strings"
"sync"
+ "time"
"golang.org/x/sync/errgroup"
"golang.org/x/tools/go/packages"
@@ -34,6 +35,7 @@ import (
"golang.org/x/tools/gopls/internal/cache/xrefs"
"golang.org/x/tools/gopls/internal/file"
"golang.org/x/tools/gopls/internal/filecache"
+ "golang.org/x/tools/gopls/internal/hackrollout"
label1 "golang.org/x/tools/gopls/internal/label"
"golang.org/x/tools/gopls/internal/protocol"
"golang.org/x/tools/gopls/internal/protocol/command"
@@ -53,6 +55,8 @@ import (
"golang.org/x/tools/internal/typesinternal"
)
+var hackInitTime time.Time = time.Now()
+
// A Snapshot represents the current state for a given view.
//
// It is first and foremost an idempotent implementation of file.Source whose
@@ -1758,6 +1762,21 @@ func (s *Snapshot) clone(ctx, bgCtx context.Context, changed StateChange, done f
if reinit {
result.initialized = false
needsDiagnosis = true
+
+ // HACK: In golang.org/x/tools/gopls/internal/cache/view.go, we intentionally
+ // no-op the initialize routine if hackrollout is enabled. Thus, any future
+ // attempts to initialize the snapshot will leave gopls in an indeterminate state.
+ // If we hit this case, just panic and let gopls restart.
+ //
+ // We need the initial initialization to succeed (even if it just no-ops). There
+ // are two underlying assumptions here:
+ // - The first initialization attempt will succeed in the first 10s, and any
+ // subsequent initialization calls after that are sure to be "reinitializations"
+ // which we can panic on
+ // - The IDE (e.g. VScode) will auto-restart the gopls server if it crashes
+ if hackrollout.Enabled() && time.Now().Sub(hackInitTime) > time.Second*10 {
+ panic("hack: panic, can't reinitialize snapshot")
+ }
}
// directIDs keeps track of package IDs that have directly changed.
diff --git a/internal/cache/view.go b/internal/cache/view.go
index f1a13e358daa..126d6b6ef338 100644
--- a/internal/cache/view.go
+++ b/internal/cache/view.go
@@ -27,6 +27,7 @@ import (
"golang.org/x/tools/gopls/internal/cache/metadata"
"golang.org/x/tools/gopls/internal/file"
+ "golang.org/x/tools/gopls/internal/hackrollout"
"golang.org/x/tools/gopls/internal/protocol"
"golang.org/x/tools/gopls/internal/settings"
"golang.org/x/tools/gopls/internal/util/maps"
@@ -611,6 +612,18 @@ func (s *Snapshot) initialize(ctx context.Context, firstAttempt bool) {
}
}()
+ // HACK: This is an expensive routine which loads all packages in the workspace, which doesn't
+ // scale for gocode because we run ~30k packages. If the hack is enabled, just no-op the
+ // initialization routine. Note this will cause "Find all references" to only operate on packages
+ // that have been loaded by the user, rather than workspace-wide.
+ if hackrollout.Enabled() {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+
+ s.initialized = true
+ return
+ }
+
// TODO(rFindley): we should only locate template files on the first attempt,
// or guard it via a different mechanism.
s.locateTemplateFiles(ctx)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment