Skip to content

Instantly share code, notes, and snippets.

@tkrajina
Created April 1, 2016 05:19
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tkrajina/51c1137899913f697a19ab96da7d0d44 to your computer and use it in GitHub Desktop.
Save tkrajina/51c1137899913f697a19ab96da7d0d44 to your computer and use it in GitHub Desktop.
Golang GroupWaiter (a wrapper aroung WaitGroup)
package main
import (
"errors"
"fmt"
"sync"
"time"
)
type GroupWaiter struct {
waitGroup *sync.WaitGroup
errors []error
}
func NewGroupWaiter() *GroupWaiter {
return &GroupWaiter{
waitGroup: new(sync.WaitGroup),
errors: make([]error, 0),
}
}
func (gw *GroupWaiter) Do(f func() error) {
gw.waitGroup.Add(1)
gw.errors = append(gw.errors, nil)
index := len(gw.errors)
go func() {
defer gw.waitGroup.Done()
err := f()
if err != nil {
gw.errors[index-1] = err
}
}()
}
// Returns erros from single go routines and a cumulative errors with messages from all (if there were errors)
func (gw *GroupWaiter) Wait() ([]error, error) {
gw.waitGroup.Wait()
var result []error
var errMessage = ""
for n, _ := range gw.errors {
if gw.errors[n] != nil {
result = append(result, gw.errors[n])
if len(errMessage) > 0 {
errMessage += "\n"
}
errMessage += "ERR:" + gw.errors[n].Error()
}
}
if len(result) > 0 {
return result, errors.New(errMessage)
}
return result, nil
}
func main() {
gw := NewGroupWaiter()
gw.Do(func() error {
for i := 0; i < 10; i++ {
fmt.Println(i)
time.Sleep(time.Second / 3)
}
fmt.Println("Done")
return errors.New("Random error 1")
})
gw.Do(func() error {
for i := 0; i < 10; i++ {
fmt.Println(i)
time.Sleep(time.Second / 4)
}
fmt.Println("Done")
return errors.New("Random error 2")
})
gw.Do(func() error {
for i := 0; i < 10; i++ {
fmt.Println(i)
time.Sleep(time.Second / 5)
}
fmt.Println("Done")
return nil
})
_, err := gw.Wait()
if err != nil {
fmt.Println("ERROR:", err.Error())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment