mirror of https://github.com/docker/buildx.git
build: create error group per opt
Using the syncronization primitive, we can avoid needing to create a separate wait group. This allows us to sidestep the issue where the wait group could be completed, but the build invocation functions had not terminated - if one of the functions was to terminate with an error, then it was possible to encounter a race condition, where the result handling code would begin executing, despite an error. The refactor to use a separate error group which more elegantly handles the concept of function returns and errors, ensures that we can't encounter this issue. Signed-off-by: Justin Chadwell <me@jedevc.com>
This commit is contained in:
parent
1180d919f5
commit
8b7aa1a168
|
@ -946,10 +946,10 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
|
|||
if multiTarget {
|
||||
span, ctx = tracing.StartSpan(ctx, k)
|
||||
}
|
||||
baseCtx := ctx
|
||||
|
||||
res := make([]*client.SolveResponse, len(dps))
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(len(dps))
|
||||
eg2, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
var pushNames string
|
||||
var insecurePush bool
|
||||
|
@ -987,9 +987,8 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
|
|||
pw := progress.WithPrefix(w, k, multiTarget)
|
||||
|
||||
c := clients[dp.driverIndex]
|
||||
eg.Go(func() error {
|
||||
eg2.Go(func() error {
|
||||
pw = progress.ResetTime(pw)
|
||||
defer wg.Done()
|
||||
|
||||
if err := waitContextDeps(ctx, dp.driverIndex, results, &so); err != nil {
|
||||
return err
|
||||
|
@ -1122,17 +1121,15 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
|
|||
}
|
||||
|
||||
eg.Go(func() (err error) {
|
||||
ctx := baseCtx
|
||||
defer func() {
|
||||
if span != nil {
|
||||
tracing.FinishWithError(span, err)
|
||||
}
|
||||
}()
|
||||
pw := progress.WithPrefix(w, "default", false)
|
||||
wg.Wait()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
if err := eg2.Wait(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
respMu.Lock()
|
||||
|
|
Loading…
Reference in New Issue