summaryrefslogtreecommitdiff
path: root/pkg/parallel/ctr/ctr.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/parallel/ctr/ctr.go')
-rw-r--r--pkg/parallel/ctr/ctr.go40
1 files changed, 40 insertions, 0 deletions
diff --git a/pkg/parallel/ctr/ctr.go b/pkg/parallel/ctr/ctr.go
new file mode 100644
index 000000000..e8c1292b8
--- /dev/null
+++ b/pkg/parallel/ctr/ctr.go
@@ -0,0 +1,40 @@
+package ctr
+
+import (
+ "context"
+
+ "github.com/containers/podman/v2/libpod"
+ "github.com/containers/podman/v2/pkg/parallel"
+ "github.com/sirupsen/logrus"
+)
+
+// ContainerOp performs the given function on the given set of
+// containers, using a number of parallel threads.
+// If no error is returned, each container specified in ctrs will have an entry
+// in the resulting map; containers with no error will be set to nil.
+func ContainerOp(ctx context.Context, ctrs []*libpod.Container, applyFunc func(*libpod.Container) error) (map[*libpod.Container]error, error) {
+ // We could use a sync.Map but given Go's lack of generic I'd rather
+ // just use a lock on a normal map...
+ // The expectation is that most of the time is spent in applyFunc
+ // anyways.
+ var (
+ errMap = make(map[*libpod.Container]<-chan error)
+ )
+
+ for _, ctr := range ctrs {
+ c := ctr
+ logrus.Debugf("Starting parallel job on container %s", c.ID())
+ errChan := parallel.Enqueue(ctx, func() error {
+ return applyFunc(c)
+ })
+ errMap[c] = errChan
+ }
+
+ finalErr := make(map[*libpod.Container]error)
+ for ctr, errChan := range errMap {
+ err := <-errChan
+ finalErr[ctr] = err
+ }
+
+ return finalErr, nil
+}