internal/sync: replace go-multierror.Group with golang.org/x/sync/errgroup

The go-multierror Group is just a shallow wrapper around sync.WaitGroup;
https://github.com/hashicorp/go-multierror/blob/v1.1.1/group.go#L5-L38

It does not limit concurrency, but handles synchronisation to collect
all errors (if any) in a go-multierror.

This patch replaces the go-multierror.Group for a sync.ErrGroup (which
is slightly easier to use, and does allow for limiting concurrency if
wanted), and a basic slice with mutex to collect the errors and to produce
a stdlib multi-error through errors.Join

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2025-08-22 15:56:19 +02:00 committed by Nicolas De loof
parent ba3f5664c0
commit 93dd1a4558

View File

@ -29,11 +29,11 @@ import (
"path"
"path/filepath"
"strings"
"github.com/hashicorp/go-multierror"
"sync"
"github.com/docker/docker/api/types/container"
"github.com/moby/go-archive"
"golang.org/x/sync/errgroup"
)
type archiveEntry struct {
@ -84,7 +84,14 @@ func (t *Tar) Sync(ctx context.Context, service string, paths []*PathMapping) er
if len(pathsToDelete) != 0 {
deleteCmd = append([]string{"rm", "-rf"}, pathsToDelete...)
}
var eg multierror.Group
var (
eg errgroup.Group
errMu sync.Mutex
errs = make([]error, 0, len(containers)*2) // max 2 errs per container
)
eg.SetLimit(16) // arbitrary limit, adjust to taste :D
for i := range containers {
containerID := containers[i].ID
tarReader := tarArchive(pathsToCopy)
@ -92,17 +99,23 @@ func (t *Tar) Sync(ctx context.Context, service string, paths []*PathMapping) er
eg.Go(func() error {
if len(deleteCmd) != 0 {
if err := t.client.Exec(ctx, containerID, deleteCmd, nil); err != nil {
return fmt.Errorf("deleting paths in %s: %w", containerID, err)
errMu.Lock()
errs = append(errs, fmt.Errorf("deleting paths in %s: %w", containerID, err))
errMu.Unlock()
}
}
if err := t.client.Untar(ctx, containerID, tarReader); err != nil {
return fmt.Errorf("copying files to %s: %w", containerID, err)
errMu.Lock()
errs = append(errs, fmt.Errorf("copying files to %s: %w", containerID, err))
errMu.Unlock()
}
return nil
return nil // don't fail-fast; collect all errors
})
}
return eg.Wait().ErrorOrNil()
_ = eg.Wait()
return errors.Join(errs...)
}
type ArchiveBuilder struct {