Skip to content

Commit dd0410f

Browse files
committed
go/packages: stop loading packages when context is done
The value of ld.Context.Err() is now always checked once at the beginning of loadPackage before it begins reading files or exportdata. loadPackage stops early if ld.Context is done. If any packages failed to load due to stopping early, Load returns (nil, ld.Context.Err()). As a side-effect, this resolves logging ld.Context.Err() multiple times per packages as unknown internal errors. (These are not internal errors nor are they unknown.) Change-Id: Iab8eedbe19ad07b592b3003d2934b20039e54a94 Reviewed-on: https://go-review.googlesource.com/c/tools/+/577395 Reviewed-by: Alan Donovan <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent dcccb2d commit dd0410f

File tree

1 file changed

+25
-10
lines changed

1 file changed

+25
-10
lines changed

go/packages/packages.go

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,8 @@ type Config struct {
129129
Mode LoadMode
130130

131131
// Context specifies the context for the load operation.
132-
// If the context is cancelled, the loader may stop early
133-
// and return an ErrCancelled error.
134-
// If Context is nil, the load cannot be cancelled.
132+
// Cancelling the context may cause [Load] to abort and
133+
// return an error.
135134
Context context.Context
136135

137136
// Logf is the logger for the config.
@@ -214,8 +213,8 @@ type Config struct {
214213
// Config specifies loading options;
215214
// nil behaves the same as an empty Config.
216215
//
217-
// Load returns an error if any of the patterns was invalid
218-
// as defined by the underlying build system.
216+
// If any of the patterns was invalid as defined by the
217+
// underlying build system, Load returns an error.
219218
// It may return an empty list of packages without an error,
220219
// for instance for an empty expansion of a valid wildcard.
221220
// Errors associated with a particular package are recorded in the
@@ -858,6 +857,12 @@ func (ld *loader) refine(response *DriverResponse) ([]*Package, error) {
858857
wg.Wait()
859858
}
860859

860+
// If the context is done, return its error and
861+
// throw out [likely] incomplete packages.
862+
if err := ld.Context.Err(); err != nil {
863+
return nil, err
864+
}
865+
861866
result := make([]*Package, len(initial))
862867
for i, lpkg := range initial {
863868
result[i] = lpkg.Package
@@ -953,6 +958,14 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
953958
lpkg.Types = types.NewPackage(lpkg.PkgPath, lpkg.Name)
954959
lpkg.Fset = ld.Fset
955960

961+
// Start shutting down if the context is done and do not load
962+
// source or export data files.
963+
// Packages that import this one will have ld.Context.Err() != nil.
964+
// ld.Context.Err() will be returned later by refine.
965+
if ld.Context.Err() != nil {
966+
return
967+
}
968+
956969
// Subtle: we populate all Types fields with an empty Package
957970
// before loading export data so that export data processing
958971
// never has to create a types.Package for an indirect dependency,
@@ -1072,6 +1085,13 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
10721085
return
10731086
}
10741087

1088+
// Start shutting down if the context is done and do not type check.
1089+
// Packages that import this one will have ld.Context.Err() != nil.
1090+
// ld.Context.Err() will be returned later by refine.
1091+
if ld.Context.Err() != nil {
1092+
return
1093+
}
1094+
10751095
lpkg.TypesInfo = &types.Info{
10761096
Types: make(map[ast.Expr]types.TypeAndValue),
10771097
Defs: make(map[*ast.Ident]types.Object),
@@ -1249,11 +1269,6 @@ func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) {
12491269
parsed := make([]*ast.File, n)
12501270
errors := make([]error, n)
12511271
for i, file := range filenames {
1252-
if ld.Config.Context.Err() != nil {
1253-
parsed[i] = nil
1254-
errors[i] = ld.Config.Context.Err()
1255-
continue
1256-
}
12571272
wg.Add(1)
12581273
go func(i int, filename string) {
12591274
parsed[i], errors[i] = ld.parseFile(filename)

0 commit comments

Comments
 (0)