Created
April 1, 2016 05:19
-
-
Save tkrajina/51c1137899913f697a19ab96da7d0d44 to your computer and use it in GitHub Desktop.
Golang GroupWaiter (a wrapper aroung WaitGroup)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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