Browse code

Merge pull request #26778 from WeiZhang555/parallel-operations

Support parallel kill,rm

Sebastiaan van Stijn authored on 2016/10/11 01:31:10
Showing 3 changed files
... ...
@@ -39,8 +39,11 @@ func NewKillCommand(dockerCli *command.DockerCli) *cobra.Command {
39 39
 func runKill(dockerCli *command.DockerCli, opts *killOptions) error {
40 40
 	var errs []string
41 41
 	ctx := context.Background()
42
+	errChan := parallelOperation(ctx, opts.containers, func(ctx context.Context, container string) error {
43
+		return dockerCli.Client().ContainerKill(ctx, container, opts.signal)
44
+	})
42 45
 	for _, name := range opts.containers {
43
-		if err := dockerCli.Client().ContainerKill(ctx, name, opts.signal); err != nil {
46
+		if err := <-errChan; err != nil {
44 47
 			errs = append(errs, err.Error())
45 48
 		} else {
46 49
 			fmt.Fprintf(dockerCli.Out(), "%s\n", name)
... ...
@@ -45,13 +45,22 @@ func runRm(dockerCli *command.DockerCli, opts *rmOptions) error {
45 45
 	ctx := context.Background()
46 46
 
47 47
 	var errs []string
48
-	for _, name := range opts.containers {
49
-		if name == "" {
48
+	options := types.ContainerRemoveOptions{
49
+		RemoveVolumes: opts.rmVolumes,
50
+		RemoveLinks:   opts.rmLink,
51
+		Force:         opts.force,
52
+	}
53
+
54
+	errChan := parallelOperation(ctx, opts.containers, func(ctx context.Context, container string) error {
55
+		if container == "" {
50 56
 			return fmt.Errorf("Container name cannot be empty")
51 57
 		}
52
-		name = strings.Trim(name, "/")
58
+		container = strings.Trim(container, "/")
59
+		return dockerCli.Client().ContainerRemove(ctx, container, options)
60
+	})
53 61
 
54
-		if err := removeContainer(dockerCli, ctx, name, opts.rmVolumes, opts.rmLink, opts.force); err != nil {
62
+	for _, name := range opts.containers {
63
+		if err := <-errChan; err != nil {
55 64
 			errs = append(errs, err.Error())
56 65
 		} else {
57 66
 			fmt.Fprintf(dockerCli.Out(), "%s\n", name)
... ...
@@ -62,15 +71,3 @@ func runRm(dockerCli *command.DockerCli, opts *rmOptions) error {
62 62
 	}
63 63
 	return nil
64 64
 }
65
-
66
-func removeContainer(dockerCli *command.DockerCli, ctx context.Context, container string, removeVolumes, removeLinks, force bool) error {
67
-	options := types.ContainerRemoveOptions{
68
-		RemoveVolumes: removeVolumes,
69
-		RemoveLinks:   removeLinks,
70
-		Force:         force,
71
-	}
72
-	if err := dockerCli.Client().ContainerRemove(ctx, container, options); err != nil {
73
-		return err
74
-	}
75
-	return nil
76
-}
... ...
@@ -99,8 +99,8 @@ func getExitCode(dockerCli *command.DockerCli, ctx context.Context, containerID
99 99
 	return c.State.Running, c.State.ExitCode, nil
100 100
 }
101 101
 
102
-func parallelOperation(ctx context.Context, cids []string, op func(ctx context.Context, id string) error) chan error {
103
-	if len(cids) == 0 {
102
+func parallelOperation(ctx context.Context, containers []string, op func(ctx context.Context, container string) error) chan error {
103
+	if len(containers) == 0 {
104 104
 		return nil
105 105
 	}
106 106
 	const defaultParallel int = 50
... ...
@@ -109,18 +109,18 @@ func parallelOperation(ctx context.Context, cids []string, op func(ctx context.C
109 109
 
110 110
 	// make sure result is printed in correct order
111 111
 	output := map[string]chan error{}
112
-	for _, c := range cids {
112
+	for _, c := range containers {
113 113
 		output[c] = make(chan error, 1)
114 114
 	}
115 115
 	go func() {
116
-		for _, c := range cids {
116
+		for _, c := range containers {
117 117
 			err := <-output[c]
118 118
 			errChan <- err
119 119
 		}
120 120
 	}()
121 121
 
122 122
 	go func() {
123
-		for _, c := range cids {
123
+		for _, c := range containers {
124 124
 			sem <- struct{}{} // Wait for active queue sem to drain.
125 125
 			go func(container string) {
126 126
 				output[container] <- op(ctx, container)