Skip to content

Commit f6f29a4

Browse files
authored
Merge pull request docker#10133 from ndeloof/build_concurrency
limit build concurrency according to --parallel
2 parents d5e4f00 + aa5cdf2 commit f6f29a4

File tree

3 files changed

+30
-12
lines changed

3 files changed

+30
-12
lines changed

cmd/compose/compose.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"os"
2323
"os/signal"
2424
"path/filepath"
25+
"strconv"
2526
"strings"
2627
"syscall"
2728

@@ -324,6 +325,13 @@ func RootCommand(streams api.Streams, backend api.Service) *cobra.Command { //no
324325
return err
325326
}
326327
}
328+
if v, ok := os.LookupEnv("COMPOSE_PARALLEL_LIMIT"); ok && !cmd.Flags().Changed("parallel") {
329+
i, err := strconv.Atoi(v)
330+
if err != nil {
331+
return fmt.Errorf("COMPOSE_PARALLEL_LIMIT must be an integer (found: %q)", v)
332+
}
333+
parallel = i
334+
}
327335
if parallel > 0 {
328336
backend.MaxConcurrency(parallel)
329337
}

pkg/compose/build.go

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,16 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
5151
opts := map[string]build.Options{}
5252
args := flatten(options.Args.Resolve(envResolver(project.Environment)))
5353

54-
services, err := project.GetServices(options.Services...)
55-
if err != nil {
56-
return err
57-
}
58-
59-
for _, service := range services {
54+
return InDependencyOrder(ctx, project, func(ctx context.Context, name string) error {
55+
if len(options.Services) > 0 && !utils.Contains(options.Services, name) {
56+
return nil
57+
}
58+
service, err := project.GetService(name)
59+
if err != nil {
60+
return err
61+
}
6062
if service.Build == nil {
61-
continue
63+
return nil
6264
}
6365
imageName := api.GetImageNameOrDefault(service, project.Name)
6466
buildOptions, err := s.toBuildOptions(project, service, imageName, options.SSHs)
@@ -91,10 +93,11 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
9193
}}
9294
}
9395
opts[imageName] = buildOptions
94-
}
95-
96-
_, err = s.doBuild(ctx, project, opts, options.Progress)
97-
return err
96+
_, err = s.doBuild(ctx, project, opts, options.Progress)
97+
return err
98+
}, func(traversal *graphTraversal) {
99+
traversal.maxConcurrency = s.maxConcurrency
100+
})
98101
}
99102

100103
func (s *composeService) ensureImagesExists(ctx context.Context, project *types.Project, quietPull bool) error {

pkg/compose/dependencies.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ type graphTraversal struct {
4747
targetServiceStatus ServiceStatus
4848
adjacentServiceStatusToSkip ServiceStatus
4949

50-
visitorFn func(context.Context, string) error
50+
visitorFn func(context.Context, string) error
51+
maxConcurrency int
5152
}
5253

5354
func upDirectionTraversal(visitorFn func(context.Context, string) error) *graphTraversal {
@@ -79,6 +80,9 @@ func InDependencyOrder(ctx context.Context, project *types.Project, fn func(cont
7980
return err
8081
}
8182
t := upDirectionTraversal(fn)
83+
for _, option := range options {
84+
option(t)
85+
}
8286
return t.visit(ctx, graph)
8387
}
8488

@@ -96,6 +100,9 @@ func (t *graphTraversal) visit(ctx context.Context, g *Graph) error {
96100
nodes := t.extremityNodesFn(g)
97101

98102
eg, ctx := errgroup.WithContext(ctx)
103+
if t.maxConcurrency > 0 {
104+
eg.SetLimit(t.maxConcurrency)
105+
}
99106
t.run(ctx, g, eg, nodes)
100107

101108
return eg.Wait()

0 commit comments

Comments
 (0)