mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-09-26 05:59:02 -04:00
Bumps [github.com/olekukonko/errors](https://github.com/olekukonko/errors) from 1.2.0 to 1.3.0. - [Commits](https://github.com/olekukonko/errors/compare/v1.2.0...v1.3.0) --- updated-dependencies: - dependency-name: github.com/olekukonko/errors dependency-version: 1.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
120 lines
3.4 KiB
Go
120 lines
3.4 KiB
Go
// Group runs multiple functions concurrently and collects all errors into a
|
|
// *MultiError. It is the error-aware counterpart to sync/errgroup: errgroup
|
|
// stops at the first failure; Group collects every failure.
|
|
|
|
package errors
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
)
|
|
|
|
// Group runs goroutines concurrently and collects every error they return.
|
|
// The zero value is ready to use; options may be applied via NewGroup.
|
|
//
|
|
// Example — fan-out with full error collection:
|
|
//
|
|
// g := errors.NewGroup()
|
|
// g.Go(func() error { return validateUser(id) })
|
|
// g.Go(func() error { return validatePerms(id) })
|
|
// if err := g.Wait(); err != nil {
|
|
// // err is *MultiError containing all failures
|
|
// log.Println(err)
|
|
// }
|
|
type Group struct {
|
|
wg sync.WaitGroup
|
|
errs *MultiError
|
|
ctx context.Context
|
|
cancel context.CancelFunc
|
|
cancelOnFirst bool
|
|
}
|
|
|
|
// GroupOption configures a Group.
|
|
type GroupOption func(*Group)
|
|
|
|
// GroupWithContext attaches ctx to the Group. The ctx is passed to
|
|
// context-aware Go calls (GoCtx). If cancelOnFirst is true, the context
|
|
// is cancelled as soon as the first error is returned by any goroutine —
|
|
// useful for "cancel siblings on first failure" patterns.
|
|
func GroupWithContext(ctx context.Context, cancelOnFirst bool) GroupOption {
|
|
return func(g *Group) {
|
|
g.ctx, g.cancel = context.WithCancel(ctx)
|
|
g.cancelOnFirst = cancelOnFirst
|
|
}
|
|
}
|
|
|
|
// GroupWithLimit sets a maximum error limit on the underlying MultiError.
|
|
// Errors beyond the limit are dropped.
|
|
func GroupWithLimit(n int) GroupOption {
|
|
return func(g *Group) {
|
|
g.errs = NewMultiError(WithLimit(n))
|
|
}
|
|
}
|
|
|
|
// NewGroup creates a Group with the given options applied.
|
|
func NewGroup(opts ...GroupOption) *Group {
|
|
g := &Group{
|
|
errs: NewMultiError(),
|
|
}
|
|
for _, o := range opts {
|
|
o(g)
|
|
}
|
|
if g.ctx == nil {
|
|
g.ctx = context.Background()
|
|
}
|
|
return g
|
|
}
|
|
|
|
// Go starts fn in a new goroutine. Errors returned by fn are collected;
|
|
// nil returns are ignored. Thread-safe: MultiError.Add handles its own locking.
|
|
// cancelOnFirst is read-only after construction so no lock is needed.
|
|
func (g *Group) Go(fn func() error) {
|
|
g.wg.Add(1)
|
|
go func() {
|
|
defer g.wg.Done()
|
|
if err := fn(); err != nil {
|
|
g.errs.Add(err) // MultiError.Add is internally mutex-protected
|
|
if g.cancelOnFirst && g.cancel != nil {
|
|
g.cancel()
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
// GoCtx starts fn in a new goroutine, passing the group's context.
|
|
// If the group was created with GroupWithContext, fn receives a context
|
|
// that is cancelled when cancelOnFirst triggers or the parent is done.
|
|
func (g *Group) GoCtx(fn func(ctx context.Context) error) {
|
|
g.wg.Add(1)
|
|
go func() {
|
|
defer g.wg.Done()
|
|
if err := fn(g.ctx); err != nil {
|
|
g.errs.Add(err) // MultiError.Add is internally mutex-protected
|
|
if g.cancelOnFirst && g.cancel != nil {
|
|
g.cancel()
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
// Wait blocks until all goroutines have finished and returns a *MultiError
|
|
// containing every error collected, or nil if all succeeded.
|
|
// Always returns *MultiError (never collapses to a raw error) so callers
|
|
// can reliably type-assert the result.
|
|
func (g *Group) Wait() error {
|
|
g.wg.Wait()
|
|
if g.cancel != nil {
|
|
g.cancel() // release context resources
|
|
}
|
|
if !g.errs.Has() {
|
|
return nil
|
|
}
|
|
return g.errs
|
|
}
|
|
|
|
// Errors returns a snapshot of errors collected so far.
|
|
// Safe to call concurrently with Go/GoCtx; may be incomplete before Wait returns.
|
|
func (g *Group) Errors() []error {
|
|
return g.errs.Errors()
|
|
}
|