Created
November 19, 2021 09:17
-
-
Save igavrysh/dd548d8d5bc5808b739d71f30d46e0da to your computer and use it in GitHub Desktop.
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 ( | |
| "fmt" | |
| "log" | |
| "math/rand" | |
| "sync" | |
| "time" | |
| ) | |
| var rng = rand.New(rand.NewSource(time.Now().UnixNano())) | |
| func main() { | |
| in, out := Start[int](10) | |
| go func() { | |
| // Produce random numbers. | |
| for i := 0; i < 1000; i++ { | |
| in <- func() (int, error) { | |
| return rng.Intn(100), nil | |
| } | |
| } | |
| close(in) | |
| }() | |
| // Consume the produced numbers and sum them up. | |
| sum := 0 | |
| for res := range out { | |
| if res.Err != nil { | |
| log.Fatalf("Error: %v", res.Err) | |
| } | |
| sum += res.Value | |
| } | |
| fmt.Printf("Total: %d\n", sum) | |
| } | |
| type Result[T any] struct { | |
| Value T | |
| Err error | |
| } | |
| type In[T any] chan<- func() (T, error) | |
| type Out[T any] <-chan Result[T] | |
| // Start creates a worker pool consisting of the given number of concurrent workers that will call | |
| // functions from the returned input channel. | |
| // The result of the function call will be sent to the returned output channel. | |
| func Start[T any](concurrency int) (In[T], Out[T]) { | |
| in := make(chan func() (T, error)) | |
| out := make(chan Result[T]) | |
| var wg sync.WaitGroup | |
| wg.Add(concurrency) | |
| for i := 0; i < concurrency; i++ { | |
| // Start a worker in a goroutine. | |
| go func() { | |
| for f := range in { | |
| v, err := f() | |
| out <- Result[T]{Value: v, Err: err} | |
| } | |
| wg.Done() | |
| }() | |
| } | |
| // Start an extra goroutine that is responsible to close the output channel | |
| // when the processing has finished. | |
| go func() { | |
| wg.Wait() | |
| close(out) | |
| }() | |
| return in, out | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment