Skip to content

Commit 2a03e9e

Browse files
committed
internal/lsp: avoid using the importer's context as much as possible
There are issues with contexts being propagated through the calls to type-checking, and I think that a lot of these were related to us using the importer's context. Instead, we should propagate the context from the store as much as possible - only using the importer's context when absolutely necessary (in the call to Import). This change propagates the correct context where possible. Updates golang/go#34103 Change-Id: I4bdc37d014ee1f775b720c9e7ad8abffffcf6ba3 Reviewed-on: https://go-review.googlesource.com/c/tools/+/193480 Run-TryBot: Rebecca Stambler <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Cottrell <[email protected]>
1 parent adb4574 commit 2a03e9e

File tree

2 files changed

+21
-29
lines changed

2 files changed

+21
-29
lines changed

internal/lsp/cache/check.go

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ func (pkg *pkg) GetImport(ctx context.Context, pkgPath string) (source.Package,
7878
}
7979

8080
// checkPackageHandle returns a source.CheckPackageHandle for a given package and config.
81-
func (imp *importer) checkPackageHandle(m *metadata) (*checkPackageHandle, error) {
82-
phs, err := imp.parseGoHandles(m)
81+
func (imp *importer) checkPackageHandle(ctx context.Context, m *metadata) (*checkPackageHandle, error) {
82+
phs, err := imp.parseGoHandles(ctx, m)
8383
if err != nil {
8484
return nil, err
8585
}
@@ -94,15 +94,8 @@ func (imp *importer) checkPackageHandle(m *metadata) (*checkPackageHandle, error
9494
imports: make(map[packagePath]*checkPackageHandle),
9595
}
9696
h := imp.view.session.cache.store.Bind(key, func(ctx context.Context) interface{} {
97-
origCtx := imp.ctx
98-
defer func() { imp.ctx = origCtx }()
99-
100-
// We must use the store's detached context to avoid poisoning the
101-
// cache with context.Canceled if the request is cancelled.
102-
imp.ctx = ctx
103-
10497
data := &checkPackageData{}
105-
data.pkg, data.err = imp.typeCheck(cph, m)
98+
data.pkg, data.err = imp.typeCheck(ctx, cph, m)
10699
return data
107100
})
108101
cph.handle = h
@@ -156,19 +149,19 @@ func (cph *checkPackageHandle) Cached(ctx context.Context) (source.Package, erro
156149
return data.pkg, data.err
157150
}
158151

159-
func (imp *importer) parseGoHandles(m *metadata) ([]source.ParseGoHandle, error) {
152+
func (imp *importer) parseGoHandles(ctx context.Context, m *metadata) ([]source.ParseGoHandle, error) {
160153
phs := make([]source.ParseGoHandle, 0, len(m.files))
161154
for _, uri := range m.files {
162155
// Call the unlocked version of getFile since we are holding the view's mutex.
163-
f, err := imp.view.GetFile(imp.ctx, uri)
156+
f, err := imp.view.GetFile(ctx, uri)
164157
if err != nil {
165158
return nil, err
166159
}
167160
gof, ok := f.(*goFile)
168161
if !ok {
169162
return nil, errors.Errorf("%s is not a Go file", f.URI())
170163
}
171-
fh := gof.Handle(imp.ctx)
164+
fh := gof.Handle(ctx)
172165
mode := source.ParseExported
173166
if imp.topLevelPackageID == m.id {
174167
mode = source.ParseFull
@@ -201,14 +194,14 @@ func (imp *importer) Import(pkgPath string) (*types.Package, error) {
201194
}
202195
imp.parentPkg.imports[packagePath(pkgPath)] = pkg
203196
// Add every file in this package to our cache.
204-
if err := imp.cachePackage(cph, pkg, cph.m); err != nil {
197+
if err := imp.cachePackage(imp.ctx, cph, pkg, cph.m); err != nil {
205198
return nil, err
206199
}
207200
return pkg.GetTypes(), nil
208201
}
209202

210-
func (imp *importer) typeCheck(cph *checkPackageHandle, m *metadata) (*pkg, error) {
211-
ctx, done := trace.StartSpan(imp.ctx, "cache.importer.typeCheck")
203+
func (imp *importer) typeCheck(ctx context.Context, cph *checkPackageHandle, m *metadata) (*pkg, error) {
204+
ctx, done := trace.StartSpan(ctx, "cache.importer.typeCheck")
212205
defer done()
213206

214207
pkg := &pkg{
@@ -234,11 +227,11 @@ func (imp *importer) typeCheck(cph *checkPackageHandle, m *metadata) (*pkg, erro
234227
pkg.errors = append(m.errors, err)
235228
}
236229
// Set imports of package to correspond to cached packages.
237-
cimp := imp.child(pkg, cph)
230+
cimp := imp.child(ctx, pkg, cph)
238231
for _, child := range m.children {
239-
childHandle, err := cimp.checkPackageHandle(child)
232+
childHandle, err := cimp.checkPackageHandle(ctx, child)
240233
if err != nil {
241-
log.Error(imp.ctx, "no check package handle", err, telemetry.Package.Of(child.id))
234+
log.Error(ctx, "no check package handle", err, telemetry.Package.Of(child.id))
242235
continue
243236
}
244237
cph.imports[child.pkgPath] = childHandle
@@ -299,7 +292,7 @@ func (imp *importer) typeCheck(cph *checkPackageHandle, m *metadata) (*pkg, erro
299292
return pkg, nil
300293
}
301294

302-
func (imp *importer) child(pkg *pkg, cph *checkPackageHandle) *importer {
295+
func (imp *importer) child(ctx context.Context, pkg *pkg, cph *checkPackageHandle) *importer {
303296
// Handle circular imports by copying previously seen imports.
304297
seen := make(map[packageID]struct{})
305298
for k, v := range imp.seen {
@@ -308,7 +301,7 @@ func (imp *importer) child(pkg *pkg, cph *checkPackageHandle) *importer {
308301
seen[pkg.id] = struct{}{}
309302
return &importer{
310303
view: imp.view,
311-
ctx: imp.ctx,
304+
ctx: ctx,
312305
config: imp.config,
313306
seen: seen,
314307
topLevelPackageID: imp.topLevelPackageID,
@@ -317,25 +310,25 @@ func (imp *importer) child(pkg *pkg, cph *checkPackageHandle) *importer {
317310
}
318311
}
319312

320-
func (imp *importer) cachePackage(cph *checkPackageHandle, pkg *pkg, m *metadata) error {
313+
func (imp *importer) cachePackage(ctx context.Context, cph *checkPackageHandle, pkg *pkg, m *metadata) error {
321314
for _, ph := range pkg.files {
322315
uri := ph.File().Identity().URI
323-
f, err := imp.view.GetFile(imp.ctx, uri)
316+
f, err := imp.view.GetFile(ctx, uri)
324317
if err != nil {
325318
return errors.Errorf("no such file %s: %v", uri, err)
326319
}
327320
gof, ok := f.(*goFile)
328321
if !ok {
329322
return errors.Errorf("%s is not a Go file", uri)
330323
}
331-
if err := imp.cachePerFile(gof, ph, cph, m); err != nil {
324+
if err := imp.cachePerFile(ctx, gof, ph, cph, m); err != nil {
332325
return errors.Errorf("failed to cache file %s: %v", gof.URI(), err)
333326
}
334327
}
335328
return nil
336329
}
337330

338-
func (imp *importer) cachePerFile(gof *goFile, ph source.ParseGoHandle, cph source.CheckPackageHandle, m *metadata) error {
331+
func (imp *importer) cachePerFile(ctx context.Context, gof *goFile, ph source.ParseGoHandle, cph source.CheckPackageHandle, m *metadata) error {
339332
gof.mu.Lock()
340333
defer gof.mu.Unlock()
341334

@@ -345,7 +338,7 @@ func (imp *importer) cachePerFile(gof *goFile, ph source.ParseGoHandle, cph sour
345338
}
346339
gof.pkgs[m.id] = cph
347340

348-
file, err := ph.Parse(imp.ctx)
341+
file, err := ph.Parse(ctx)
349342
if file == nil {
350343
return errors.Errorf("no AST for %s: %v", ph.File().Identity().URI, err)
351344
}

internal/lsp/cache/load.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,11 @@ func (view *view) loadParseTypecheck(ctx context.Context, f *goFile) error {
2626
for _, m := range pkgs {
2727
imp := &importer{
2828
view: view,
29-
ctx: ctx,
3029
config: view.Config(ctx),
3130
seen: make(map[packageID]struct{}),
3231
topLevelPackageID: m.id,
3332
}
34-
cph, err := imp.checkPackageHandle(m)
33+
cph, err := imp.checkPackageHandle(ctx, m)
3534
if err != nil {
3635
log.Error(ctx, "failed to get CheckPackgeHandle", err)
3736
continue
@@ -42,7 +41,7 @@ func (view *view) loadParseTypecheck(ctx context.Context, f *goFile) error {
4241
continue
4342
}
4443
// Cache this package on the file object, since all dependencies are cached in the Import function.
45-
imp.cachePackage(cph, pkg, m)
44+
imp.cachePackage(ctx, cph, pkg, m)
4645
}
4746
return nil
4847
}

0 commit comments

Comments
 (0)