浏览代码

fix race condition, waiting for containers when one exit

Signed-off-by: Nicolas De Loof <[email protected]>
Nicolas De Loof 2 年之前
父节点
当前提交
a2ce602f6c
共有 2 个文件被更改,包括 14 次插入9 次删除
  1. 13 9
      pkg/compose/dependencies.go
  2. 1 0
      pkg/compose/run.go

+ 13 - 9
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

+ 1 - 0
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...)