Skip to content

Commit

Permalink
cmd/go: propagate context into PackagesForBuild and Do for tracing
Browse files Browse the repository at this point in the history
This change propagates context into PackagesForErrors and Do for
the purpose of tracing, and calls trace.StartSpan on PackagesForErrors
and Do, so that the trace now shows the broad outline of where
the "Loading" and "Execution" phases are in the build.

Updates #38714

Change-Id: Ib9a7cf7030210f68f76663d1c8a7461e0a226611
Reviewed-on: https://go-review.googlesource.com/c/go/+/238541
Run-TryBot: Michael Matloob <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Jay Conrod <[email protected]>
Reviewed-by: Bryan C. Mills <[email protected]>
  • Loading branch information
matloob committed Aug 12, 2020
1 parent 14715b2 commit 2bfa45c
Show file tree
Hide file tree
Showing 13 changed files with 47 additions and 33 deletions.
2 changes: 1 addition & 1 deletion src/cmd/go/internal/clean/clean.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func runClean(ctx context.Context, cmd *base.Command, args []string) {
}

if cleanPkg {
for _, pkg := range load.PackagesAndErrors(args) {
for _, pkg := range load.PackagesAndErrors(ctx, args) {
clean(pkg)
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/go/internal/fix/fix.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ See also: go fmt, go vet.

func runFix(ctx context.Context, cmd *base.Command, args []string) {
printed := false
for _, pkg := range load.Packages(args) {
for _, pkg := range load.Packages(ctx, args) {
if modload.Enabled() && pkg.Module != nil && !pkg.Module.Main {
if !printed {
fmt.Fprintf(os.Stderr, "go: not fixing packages in dependency modules\n")
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/go/internal/fmtcmd/fmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func runFmt(ctx context.Context, cmd *base.Command, args []string) {
}
}()
}
for _, pkg := range load.PackagesAndErrors(args) {
for _, pkg := range load.PackagesAndErrors(ctx, args) {
if modload.Enabled() && pkg.Module != nil && !pkg.Module.Main {
if !printed {
fmt.Fprintf(os.Stderr, "go: not formatting packages in dependency modules\n")
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/go/internal/generate/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ func runGenerate(ctx context.Context, cmd *base.Command, args []string) {

// Even if the arguments are .go files, this loop suffices.
printed := false
for _, pkg := range load.PackagesAndErrors(args) {
for _, pkg := range load.PackagesAndErrors(ctx, args) {
if modload.Enabled() && pkg.Module != nil && !pkg.Module.Main {
if !printed {
fmt.Fprintf(os.Stderr, "go: not generating in packages in dependency modules\n")
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/go/internal/get/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
// everything.
load.ClearPackageCache()

pkgs := load.PackagesForBuild(args)
pkgs := load.PackagesForBuild(ctx, args)

// Phase 3. Install.
if *getD {
Expand All @@ -182,7 +182,7 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
return
}

work.InstallPackages(args, pkgs)
work.InstallPackages(ctx, args, pkgs)
}

// downloadPaths prepares the list of paths to pass to download.
Expand Down
6 changes: 3 additions & 3 deletions src/cmd/go/internal/list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -449,9 +449,9 @@ func runList(ctx context.Context, cmd *base.Command, args []string) {
load.IgnoreImports = *listFind
var pkgs []*load.Package
if *listE {
pkgs = load.PackagesAndErrors(args)
pkgs = load.PackagesAndErrors(ctx, args)
} else {
pkgs = load.Packages(args)
pkgs = load.Packages(ctx, args)
base.ExitIfErrors()
}

Expand Down Expand Up @@ -539,7 +539,7 @@ func runList(ctx context.Context, cmd *base.Command, args []string) {
a.Deps = append(a.Deps, b.AutoAction(work.ModeInstall, work.ModeInstall, p))
}
}
b.Do(a)
b.Do(ctx, a)
}

for _, p := range pkgs {
Expand Down
15 changes: 10 additions & 5 deletions src/cmd/go/internal/load/pkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package load

import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
Expand All @@ -30,6 +31,7 @@ import (
"cmd/go/internal/par"
"cmd/go/internal/search"
"cmd/go/internal/str"
"cmd/go/internal/trace"
)

var (
Expand Down Expand Up @@ -2123,9 +2125,9 @@ func LoadImportWithFlags(path, srcDir string, parent *Package, stk *ImportStack,
// to load dependencies of a named package, the named
// package is still returned, with p.Incomplete = true
// and details in p.DepsErrors.
func Packages(args []string) []*Package {
func Packages(ctx context.Context, args []string) []*Package {
var pkgs []*Package
for _, pkg := range PackagesAndErrors(args) {
for _, pkg := range PackagesAndErrors(ctx, args) {
if pkg.Error != nil {
base.Errorf("%v", pkg.Error)
continue
Expand All @@ -2139,7 +2141,10 @@ func Packages(args []string) []*Package {
// *Package for every argument, even the ones that
// cannot be loaded at all.
// The packages that fail to load will have p.Error != nil.
func PackagesAndErrors(patterns []string) []*Package {
func PackagesAndErrors(ctx context.Context, patterns []string) []*Package {
ctx, span := trace.StartSpan(ctx, "load.PackagesAndErrors")
defer span.Done()

for _, p := range patterns {
// Listing is only supported with all patterns referring to either:
// - Files that are part of the same directory.
Expand Down Expand Up @@ -2233,8 +2238,8 @@ func ImportPaths(args []string) []*search.Match {
// PackagesForBuild is like Packages but exits
// if any of the packages or their dependencies have errors
// (cannot be built).
func PackagesForBuild(args []string) []*Package {
pkgs := PackagesAndErrors(args)
func PackagesForBuild(ctx context.Context, args []string) []*Package {
pkgs := PackagesAndErrors(ctx, args)
printed := map[*PackageError]bool{}
for _, pkg := range pkgs {
if pkg.Error != nil {
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/go/internal/modget/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -715,8 +715,8 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
return
}
work.BuildInit()
pkgs := load.PackagesForBuild(pkgPatterns)
work.InstallPackages(pkgPatterns, pkgs)
pkgs := load.PackagesForBuild(ctx, pkgPatterns)
work.InstallPackages(ctx, pkgPatterns, pkgs)
}

// runQueries looks up modules at target versions in parallel. Results will be
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/go/internal/run/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func runRun(ctx context.Context, cmd *base.Command, args []string) {
}
p = load.GoFilesPackage(files)
} else if len(args) > 0 && !strings.HasPrefix(args[0], "-") {
pkgs := load.PackagesAndErrors(args[:1])
pkgs := load.PackagesAndErrors(ctx, args[:1])
if len(pkgs) == 0 {
base.Fatalf("go run: no packages loaded from %s", args[0])
}
Expand Down Expand Up @@ -141,7 +141,7 @@ func runRun(ctx context.Context, cmd *base.Command, args []string) {
}
a1 := b.LinkAction(work.ModeBuild, work.ModeBuild, p)
a := &work.Action{Mode: "go run", Func: buildRunProgram, Args: cmdArgs, Deps: []*work.Action{a1}}
b.Do(a)
b.Do(ctx, a)
}

// buildRunProgram is the action for running a binary that has already
Expand Down
8 changes: 4 additions & 4 deletions src/cmd/go/internal/test/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ func runTest(ctx context.Context, cmd *base.Command, args []string) {
work.VetFlags = testVet.flags
work.VetExplicit = testVet.explicit

pkgs = load.PackagesForBuild(pkgArgs)
pkgs = load.PackagesForBuild(ctx, pkgArgs)
if len(pkgs) == 0 {
base.Fatalf("no packages to test")
}
Expand Down Expand Up @@ -659,15 +659,15 @@ func runTest(ctx context.Context, cmd *base.Command, args []string) {
sort.Strings(all)

a := &work.Action{Mode: "go test -i"}
for _, p := range load.PackagesForBuild(all) {
for _, p := range load.PackagesForBuild(ctx, all) {
if cfg.BuildToolchainName == "gccgo" && p.Standard {
// gccgo's standard library packages
// can not be reinstalled.
continue
}
a.Deps = append(a.Deps, b.CompileAction(work.ModeInstall, work.ModeInstall, p))
}
b.Do(a)
b.Do(ctx, a)
if !testC || a.Failed {
return
}
Expand Down Expand Up @@ -787,7 +787,7 @@ func runTest(ctx context.Context, cmd *base.Command, args []string) {
}
}

b.Do(root)
b.Do(ctx, root)
}

// ensures that package p imports the named package
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/go/internal/vet/vet.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func runVet(ctx context.Context, cmd *base.Command, args []string) {
}
}

pkgs := load.PackagesForBuild(pkgArgs)
pkgs := load.PackagesForBuild(ctx, pkgArgs)
if len(pkgs) == 0 {
base.Fatalf("no packages to vet")
}
Expand All @@ -93,5 +93,5 @@ func runVet(ctx context.Context, cmd *base.Command, args []string) {
root.Deps = append(root.Deps, b.VetAction(work.ModeBuild, work.ModeBuild, pxtest))
}
}
b.Do(root)
b.Do(ctx, root)
}
20 changes: 12 additions & 8 deletions src/cmd/go/internal/work/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"cmd/go/internal/cfg"
"cmd/go/internal/load"
"cmd/go/internal/search"
"cmd/go/internal/trace"
)

var CmdBuild = &base.Command{
Expand Down Expand Up @@ -350,7 +351,7 @@ func runBuild(ctx context.Context, cmd *base.Command, args []string) {
var b Builder
b.Init()

pkgs := load.PackagesForBuild(args)
pkgs := load.PackagesForBuild(ctx, args)

explicitO := len(cfg.BuildO) > 0

Expand Down Expand Up @@ -379,7 +380,7 @@ func runBuild(ctx context.Context, cmd *base.Command, args []string) {
depMode = ModeInstall
}

pkgs = omitTestOnly(pkgsFilter(load.Packages(args)))
pkgs = omitTestOnly(pkgsFilter(load.Packages(ctx, args)))

// Special case -o /dev/null by not writing at all.
if cfg.BuildO == os.DevNull {
Expand Down Expand Up @@ -409,7 +410,7 @@ func runBuild(ctx context.Context, cmd *base.Command, args []string) {
if len(a.Deps) == 0 {
base.Fatalf("go build: no main packages to build")
}
b.Do(a)
b.Do(ctx, a)
return
}
if len(pkgs) > 1 {
Expand All @@ -422,7 +423,7 @@ func runBuild(ctx context.Context, cmd *base.Command, args []string) {
p.Stale = true // must build - not up to date
p.StaleReason = "build -o flag in use"
a := b.AutoAction(ModeInstall, depMode, p)
b.Do(a)
b.Do(ctx, a)
return
}

Expand All @@ -433,7 +434,7 @@ func runBuild(ctx context.Context, cmd *base.Command, args []string) {
if cfg.BuildBuildmode == "shared" {
a = b.buildmodeShared(ModeBuild, depMode, args, pkgs, a)
}
b.Do(a)
b.Do(ctx, a)
}

var CmdInstall = &base.Command{
Expand Down Expand Up @@ -518,7 +519,7 @@ func libname(args []string, pkgs []*load.Package) (string, error) {

func runInstall(ctx context.Context, cmd *base.Command, args []string) {
BuildInit()
InstallPackages(args, load.PackagesForBuild(args))
InstallPackages(ctx, args, load.PackagesForBuild(ctx, args))
}

// omitTestOnly returns pkgs with test-only packages removed.
Expand All @@ -538,7 +539,10 @@ func omitTestOnly(pkgs []*load.Package) []*load.Package {
return list
}

func InstallPackages(patterns []string, pkgs []*load.Package) {
func InstallPackages(ctx context.Context, patterns []string, pkgs []*load.Package) {
ctx, span := trace.StartSpan(ctx, "InstallPackages "+strings.Join(patterns, " "))
defer span.Done()

if cfg.GOBIN != "" && !filepath.IsAbs(cfg.GOBIN) {
base.Fatalf("cannot install, GOBIN must be an absolute path")
}
Expand Down Expand Up @@ -607,7 +611,7 @@ func InstallPackages(patterns []string, pkgs []*load.Package) {
a = b.buildmodeShared(ModeInstall, ModeInstall, patterns, pkgs, a)
}

b.Do(a)
b.Do(ctx, a)
base.ExitIfErrors()

// Success. If this command is 'go install' with no arguments
Expand Down
7 changes: 6 additions & 1 deletion src/cmd/go/internal/work/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package work

import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
Expand All @@ -31,6 +32,7 @@ import (
"cmd/go/internal/cfg"
"cmd/go/internal/load"
"cmd/go/internal/str"
"cmd/go/internal/trace"
)

// actionList returns the list of actions in the dag rooted at root
Expand All @@ -54,7 +56,10 @@ func actionList(root *Action) []*Action {
}

// do runs the action graph rooted at root.
func (b *Builder) Do(root *Action) {
func (b *Builder) Do(ctx context.Context, root *Action) {
ctx, span := trace.StartSpan(ctx, "exec.Builder.Do ("+root.Mode+" "+root.Target+")")
defer span.Done()

if !b.IsCmdList {
// If we're doing real work, take time at the end to trim the cache.
c := cache.Default()
Expand Down

0 comments on commit 2bfa45c

Please sign in to comment.