github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/parallel/ctr/ctr.go (about) 1 package ctr 2 3 import ( 4 "context" 5 6 "github.com/hanks177/podman/v4/libpod" 7 "github.com/hanks177/podman/v4/pkg/parallel" 8 "github.com/sirupsen/logrus" 9 ) 10 11 // ContainerOp performs the given function on the given set of 12 // containers, using a number of parallel threads. 13 // If no error is returned, each container specified in ctrs will have an entry 14 // in the resulting map; containers with no error will be set to nil. 15 func ContainerOp(ctx context.Context, ctrs []*libpod.Container, applyFunc func(*libpod.Container) error) (map[*libpod.Container]error, error) { 16 // We could use a sync.Map but given Go's lack of generic I'd rather 17 // just use a lock on a normal map... 18 // The expectation is that most of the time is spent in applyFunc 19 // anyways. 20 var ( 21 errMap = make(map[*libpod.Container]<-chan error) 22 ) 23 24 for _, ctr := range ctrs { 25 c := ctr 26 logrus.Debugf("Starting parallel job on container %s", c.ID()) 27 errChan := parallel.Enqueue(ctx, func() error { 28 return applyFunc(c) 29 }) 30 errMap[c] = errChan 31 } 32 33 finalErr := make(map[*libpod.Container]error) 34 for ctr, errChan := range errMap { 35 err := <-errChan 36 finalErr[ctr] = err 37 } 38 39 return finalErr, nil 40 }