Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

introduce --parallel to limit concurrent engine calls #10030

Merged
merged 1 commit into from
Dec 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 9 additions & 4 deletions cmd/compose/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,10 +263,11 @@ func RootCommand(dockerCli command.Cli, backend api.Service) *cobra.Command {

opts := projectOptions{}
var (
ansi string
noAnsi bool
verbose bool
version bool
ansi string
noAnsi bool
verbose bool
version bool
parallel int
)
c := &cobra.Command{
Short: "Docker Compose",
Expand Down Expand Up @@ -325,6 +326,9 @@ func RootCommand(dockerCli command.Cli, backend api.Service) *cobra.Command {
opts.ProjectDir = opts.WorkDir
fmt.Fprint(os.Stderr, aec.Apply("option '--workdir' is DEPRECATED at root level! Please use '--project-directory' instead.\n", aec.RedF))
}
if parallel > 0 {
backend.MaxConcurrency(parallel)
}
return nil
},
}
Expand Down Expand Up @@ -370,6 +374,7 @@ func RootCommand(dockerCli command.Cli, backend api.Service) *cobra.Command {
)

c.Flags().StringVar(&ansi, "ansi", "auto", `Control when to print ANSI control characters ("never"|"always"|"auto")`)
c.Flags().IntVar(&parallel, "parallel", -1, `Control max parallelism, -1 for unlimited`)
c.Flags().BoolVarP(&version, "version", "v", false, "Show the Docker Compose version information")
c.Flags().MarkHidden("version") //nolint:errcheck
c.Flags().BoolVar(&noAnsi, "no-ansi", false, `Do not print ANSI control characters (DEPRECATED)`)
Expand Down
1 change: 1 addition & 0 deletions docs/reference/compose.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Docker Compose
| `--compatibility` | | | Run compose in backward compatibility mode |
| `--env-file` | `string` | | Specify an alternate environment file. |
| `-f`, `--file` | `stringArray` | | Compose configuration files |
| `--parallel` | `int` | `-1` | Control max parallelism, -1 for unlimited |
| `--profile` | `stringArray` | | Specify a profile to enable |
| `--project-directory` | `string` | | Specify an alternate working directory
(default: the path of the, first specified, Compose file) |
Expand Down
10 changes: 10 additions & 0 deletions docs/reference/docker_compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,16 @@ options:
experimentalcli: false
kubernetes: false
swarm: false
- option: parallel
value_type: int
default_value: "-1"
description: Control max parallelism, -1 for unlimited
deprecated: false
hidden: false
experimental: false
experimentalcli: false
kubernetes: false
swarm: false
- option: profile
value_type: stringArray
default_value: '[]'
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ type Service interface {
Port(ctx context.Context, projectName string, service string, port uint16, options PortOptions) (string, int, error)
// Images executes the equivalent of a `compose images`
Images(ctx context.Context, projectName string, options ImagesOptions) ([]ImageSummary, error)
// MaxConcurrency defines upper limit for concurrent operations against engine API
MaxConcurrency(parallel int)
}

// BuildOptions group options of the Build API
Expand Down
6 changes: 6 additions & 0 deletions pkg/api/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type ServiceProxy struct {
EventsFn func(ctx context.Context, project string, options EventsOptions) error
PortFn func(ctx context.Context, project string, service string, port uint16, options PortOptions) (string, int, error)
ImagesFn func(ctx context.Context, projectName string, options ImagesOptions) ([]ImageSummary, error)
MaxConcurrencyFn func(parallel int)
interceptors []Interceptor
}

Expand Down Expand Up @@ -87,6 +88,7 @@ func (s *ServiceProxy) WithService(service Service) *ServiceProxy {
s.EventsFn = service.Events
s.PortFn = service.Port
s.ImagesFn = service.Images
s.MaxConcurrencyFn = service.MaxConcurrency
return s
}

Expand Down Expand Up @@ -308,3 +310,7 @@ func (s *ServiceProxy) Images(ctx context.Context, project string, options Image
}
return s.ImagesFn(ctx, project, options)
}

func (s *ServiceProxy) MaxConcurrency(i int) {
s.MaxConcurrencyFn(i)
}
10 changes: 8 additions & 2 deletions pkg/compose/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@ import (
// NewComposeService create a local implementation of the compose.Service API
func NewComposeService(dockerCli command.Cli) api.Service {
return &composeService{
dockerCli: dockerCli,
dockerCli: dockerCli,
maxConcurrency: -1,
}
}

type composeService struct {
dockerCli command.Cli
dockerCli command.Cli
maxConcurrency int
ndeloof marked this conversation as resolved.
Show resolved Hide resolved
}

func (s *composeService) apiClient() client.APIClient {
Expand All @@ -57,6 +59,10 @@ func (s *composeService) configFile() *configfile.ConfigFile {
return s.dockerCli.ConfigFile()
}

func (s *composeService) MaxConcurrency(i int) {
s.maxConcurrency = i
}

func (s *composeService) stdout() *streams.Out {
return s.dockerCli.Out()
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/compose/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ func (s *composeService) pull(ctx context.Context, project *types.Project, opts

w := progress.ContextWriter(ctx)
eg, ctx := errgroup.WithContext(ctx)
eg.SetLimit(s.maxConcurrency)

var mustBuild []string

Expand Down Expand Up @@ -279,6 +280,7 @@ func (s *composeService) pullRequiredImages(ctx context.Context, project *types.
return progress.Run(ctx, func(ctx context.Context) error {
w := progress.ContextWriter(ctx)
eg, ctx := errgroup.WithContext(ctx)
eg.SetLimit(s.maxConcurrency)
pulledImages := make([]string, len(needPull))
for i, service := range needPull {
i, service := i, service
Expand Down
1 change: 1 addition & 0 deletions pkg/compose/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func (s *composeService) Push(ctx context.Context, project *types.Project, optio

func (s *composeService) push(ctx context.Context, project *types.Project, options api.PushOptions) error {
eg, ctx := errgroup.WithContext(ctx)
eg.SetLimit(s.maxConcurrency)

info, err := s.apiClient().Info(ctx)
if err != nil {
Expand Down
12 changes: 12 additions & 0 deletions pkg/mocks/mock_docker_compose_api.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.