diff --git a/pkg/compose/dependencies.go b/pkg/compose/dependencies.go index de66f84cd..331a8001a 100644 --- a/pkg/compose/dependencies.go +++ b/pkg/compose/dependencies.go @@ -140,24 +140,28 @@ func (t *graphTraversal) visit(ctx context.Context, g *Graph) error { if t.maxConcurrency > 0 { eg.SetLimit(t.maxConcurrency + 1) } - nodeCh := make(chan *Vertex) + nodeCh := make(chan *Vertex, expect) + defer close(nodeCh) + // nodeCh need to allow n=expect writers while reader goroutine could have returner after ctx.Done eg.Go(func() error { - for node := range nodeCh { - expect-- - if expect == 0 { - close(nodeCh) + for { + select { + case <-ctx.Done(): return nil + case node := <-nodeCh: + expect-- + if expect == 0 { + return nil + } + t.run(ctx, g, eg, t.adjacentNodesFn(node), nodeCh) } - t.run(ctx, g, eg, t.adjacentNodesFn(node), nodeCh) } - return nil }) nodes := t.extremityNodesFn(g) t.run(ctx, g, eg, nodes, nodeCh) - err := eg.Wait() - return err + return eg.Wait() } // Note: this could be `graph.walk` or whatever diff --git a/pkg/compose/run.go b/pkg/compose/run.go index d84289872..22cd913c9 100644 --- a/pkg/compose/run.go +++ b/pkg/compose/run.go @@ -118,6 +118,7 @@ func applyRunOptions(project *types.Project, service *types.ServiceConfig, opts if len(opts.User) > 0 { service.User = opts.User } + if len(opts.CapAdd) > 0 { service.CapAdd = append(service.CapAdd, opts.CapAdd...) service.CapDrop = utils.Remove(service.CapDrop, opts.CapAdd...)