mirror of
https://github.com/crazybber/awesome-patterns.git
synced 2024-11-30 08:56:05 +03:00
53 lines
870 B
Go
53 lines
870 B
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"math/rand"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
func fetchAll() error {
|
||
|
var N = 4
|
||
|
quit := make(chan bool)
|
||
|
errc := make(chan error)
|
||
|
done := make(chan error)
|
||
|
for i := 0; i < N; i++ {
|
||
|
go func(i int) {
|
||
|
// dummy fetch
|
||
|
time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
|
||
|
err := error(nil)
|
||
|
if rand.Intn(2) == 0 {
|
||
|
err = fmt.Errorf("goroutine %d's error returned", i)
|
||
|
}
|
||
|
ch := done // we'll send to done if nil error and to errc otherwise
|
||
|
if err != nil {
|
||
|
ch = errc
|
||
|
}
|
||
|
select {
|
||
|
case ch <- err:
|
||
|
return
|
||
|
case <-quit:
|
||
|
return
|
||
|
}
|
||
|
}(i)
|
||
|
}
|
||
|
count := 0
|
||
|
for {
|
||
|
select {
|
||
|
case err := <-errc:
|
||
|
close(quit)
|
||
|
return err
|
||
|
case <-done:
|
||
|
count++
|
||
|
if count == N {
|
||
|
return nil // got all N signals, so there was no error
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
rand.Seed(time.Now().UnixNano())
|
||
|
fmt.Println(fetchAll())
|
||
|
}
|