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  }