Bladeren bron

Enhancement: allow parallel stop

Stop multiple containers in parallel to speed up stop process, allow
maximum 50 parallel stops.

Signed-off-by: Abhinav Dahiya <abhinavdtu2012@gmail.com>
Signed-off-by: Zhang Wei <zhangwei555@huawei.com>
Zhang Wei 9 jaren geleden
bovenliggende
commit
2155b46915
2 gewijzigde bestanden met toevoegingen van 38 en 2 verwijderingen
  1. 6 2
      cli/command/container/stop.go
  2. 32 0
      cli/command/container/utils.go

+ 6 - 2
cli/command/container/stop.go

@@ -39,11 +39,15 @@ func NewStopCommand(dockerCli *command.DockerCli) *cobra.Command {
 
 func runStop(dockerCli *command.DockerCli, opts *stopOptions) error {
 	ctx := context.Background()
+	timeout := time.Duration(opts.time) * time.Second
 
 	var errs []string
+
+	errChan := parallelOperation(ctx, opts.containers, func(ctx context.Context, id string) error {
+		return dockerCli.Client().ContainerStop(ctx, id, &timeout)
+	})
 	for _, container := range opts.containers {
-		timeout := time.Duration(opts.time) * time.Second
-		if err := dockerCli.Client().ContainerStop(ctx, container, &timeout); err != nil {
+		if err := <-errChan; err != nil {
 			errs = append(errs, err.Error())
 		} else {
 			fmt.Fprintf(dockerCli.Out(), "%s\n", container)

+ 32 - 0
cli/command/container/utils.go

@@ -90,3 +90,35 @@ func getExitCode(dockerCli *command.DockerCli, ctx context.Context, containerID
 	}
 	return c.State.Running, c.State.ExitCode, nil
 }
+
+func parallelOperation(ctx context.Context, cids []string, op func(ctx context.Context, id string) error) chan error {
+	if len(cids) == 0 {
+		return nil
+	}
+	const defaultParallel int = 50
+	sem := make(chan struct{}, defaultParallel)
+	errChan := make(chan error)
+
+	// make sure result is printed in correct order
+	output := map[string]chan error{}
+	for _, c := range cids {
+		output[c] = make(chan error, 1)
+	}
+	go func() {
+		for _, c := range cids {
+			err := <-output[c]
+			errChan <- err
+		}
+	}()
+
+	go func() {
+		for _, c := range cids {
+			sem <- struct{}{} // Wait for active queue sem to drain.
+			go func(container string) {
+				output[container] <- op(ctx, container)
+				<-sem
+			}(c)
+		}
+	}()
+	return errChan
+}