diff options
Diffstat (limited to 'pkg/parallel/ctr')
-rw-r--r-- | pkg/parallel/ctr/ctr.go | 40 |
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 +} |