Skip to content

Instantly share code, notes, and snippets.

@flymop
Created July 30, 2022 07:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save flymop/388cf5548f0ec82fe0644c8a2042fbb4 to your computer and use it in GitHub Desktop.
Save flymop/388cf5548f0ec82fe0644c8a2042fbb4 to your computer and use it in GitHub Desktop.
An example on multi producer (sender) and single consumer (receiver) golang channel
// https://go.dev/play/p/z7lFk4D-mhA
package main
import (
"context"
"fmt"
"math/rand"
"strconv"
"strings"
"sync"
"time"
)
func longRunningTask(idx int) string {
time.Sleep(time.Duration(rand.Intn(4)) * time.Second)
return "task completed: " + strconv.Itoa(idx)
}
func main() {
resultC := make(chan string, 20)
var wg sync.WaitGroup
ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
defer cancel()
rand.Seed(time.Now().UnixNano())
// run tasks
for i := 0; i < 20; i++ {
wg.Add(1)
go func(ctx context.Context, i int) {
defer wg.Done()
result := longRunningTask(i)
// ramdomly pick a case when timeout
select {
case <-ctx.Done():
return
default:
resultC <- result
}
}(ctx, i)
}
wg.Wait()
results := make([]string, 0)
runLoop:
for {
// safely drain the channel
if len(resultC) == 0 {
break runLoop
}
select {
case r := <-resultC:
results = append(results, r)
default:
}
}
// results handling, for example, print them
fmt.Printf("running task results:\n%s", strings.Join(results, ", "))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment