Skip to content

Commit

Permalink
add sync/errgroup like functionality (#28)
Browse files Browse the repository at this point in the history
add sync/errgroup like functionality
  • Loading branch information
nickethier authored Nov 20, 2019
2 parents bdca7bb + 5e6cd52 commit 72917a1
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
38 changes: 38 additions & 0 deletions group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package multierror

import "sync"

// Group is a collection of goroutines which return errors that need to be
// coalesced.
type Group struct {
mutex sync.Mutex
err *Error
wg sync.WaitGroup
}

// Go calls the given function in a new goroutine.
//
// If the function returns an error it is added to the group multierror which
// is returned by Wait.
func (g *Group) Go(f func() error) {
g.wg.Add(1)

go func() {
defer g.wg.Done()

if err := f(); err != nil {
g.mutex.Lock()
g.err = Append(g.err, err)
g.mutex.Unlock()
}
}()
}

// Wait blocks until all function calls from the Go method have returned, then
// returns the multierror.
func (g *Group) Wait() *Error {
g.wg.Wait()
g.mutex.Lock()
defer g.mutex.Unlock()
return g.err
}
44 changes: 44 additions & 0 deletions group_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package multierror

import (
"errors"
"strings"
"testing"
)

func TestGroup(t *testing.T) {
err1 := errors.New("group_test: 1")
err2 := errors.New("group_test: 2")

cases := []struct {
errs []error
nilResult bool
}{
{errs: []error{}, nilResult: true},
{errs: []error{nil}, nilResult: true},
{errs: []error{err1}},
{errs: []error{err1, nil}},
{errs: []error{err1, nil, err2}},
}

for _, tc := range cases {
var g Group

for _, err := range tc.errs {
err := err
g.Go(func() error { return err })

}

gErr := g.Wait()
if gErr != nil {
for i := range tc.errs {
if tc.errs[i] != nil && !strings.Contains(gErr.Error(), tc.errs[i].Error()) {
t.Fatalf("expected error to contain %q, actual: %v", tc.errs[i].Error(), gErr)
}
}
} else if !tc.nilResult {
t.Fatalf("Group.Wait() should not have returned nil for errs: %v", tc.errs)
}
}
}

0 comments on commit 72917a1

Please sign in to comment.