// Package task provides an alternative to errgroup package with builtin context // cancellation support. // // This packages uses go.uber.org/multierr to combine errors from failed tasks.
package task import ( ) // Task is a function that performs some work in foreground. type Task func(ctx context.Context) error // Run executes the task. func ( Task) ( context.Context) error { return () } // Named returns a task that returns an error prefixed with name on failure. func ( string, Task) Task { return func( context.Context) error { := () if == nil { return nil } return fmt.Errorf("%s: %w", , ) } } // Sequential returns a function that executes a group of tasks sequentially // using the given cancellation condition. The resulting Task returns combined // errors for all failed subtasks. func ( CancelCondition, ...Task) Task { return func( context.Context) error { var []error , := context.WithCancel() defer () for , := range { := .Run() if != nil { if == nil { = make([]error, len()) } [] = } if () { () } } return multierr.Combine(...) } } // Parallel returns a function that executes a group of tasks in parallel using // the given cancellation condition. The resulting Task returns combined errors // for all failed subtasks. func ( CancelCondition, ...Task) Task { return func( context.Context) error { var sync.Once var []error , := context.WithCancel() defer () var sync.WaitGroup .Add(len()) for , := range { , := , go func() { defer .Done() := .Run() if != nil { .Do(func() { = make([]error, len()) }) [] = } if () { () } }() } .Wait() return multierr.Combine(...) } }