Utoljára aktív 1718788939

fan in fan out mechanism example in Go

main.go Eredeti
1package main
2
3import (
4 "fmt"
5 "log"
6 "math/rand"
7 "sync"
8
9 "github.com/hashicorp/go-multierror"
10)
11
12func main() {
13 if err := runConcurrently(); err != nil {
14 log.Fatalf("errors occured: %v", err)
15 }
16 log.Printf("all done, no errors")
17}
18
19func runConcurrently() error {
20 intChan := make(chan int)
21 wg := sync.WaitGroup{}
22 workers := 5
23 errC := make(chan error)
24
25 // producer
26 wg.Add(1)
27 go func() {
28 defer wg.Done()
29 defer close(intChan)
30 // insert random numbers into the channel
31 for i := 0; i < 30; i++ {
32 intChan <- rand.Intn(100)
33 }
34 }()
35
36 // consumer
37 for i := 0; i < workers; i++ {
38 wg.Add(1)
39 go func() {
40 defer wg.Done()
41 for {
42 select {
43 case number, ok := <-intChan:
44 if !ok {
45 return
46 }
47 if err := doSomething(number); err != nil {
48 errC <- err
49 }
50 }
51 }
52 }()
53 }
54
55 go func() {
56 wg.Wait()
57 close(errC)
58 }()
59
60 var errs *multierror.Error
61
62 for {
63 select {
64 case err, ok := <-errC:
65 if !ok {
66 return errs.ErrorOrNil()
67 }
68 if err != nil {
69 errs = multierror.Append(errs, err)
70 }
71 }
72 }
73}
74
75func doSomething(i int) error {
76 if i%15 == 0 {
77 return fmt.Errorf("random error: %v", i)
78 }
79 log.Printf("doing something with %d", i)
80 return nil
81}
82