Skip to content

Instantly share code, notes, and snippets.

@dexterous
Created May 27, 2025 10:33
Show Gist options
  • Save dexterous/05761808a9e1f2e74c0181c48e41a46e to your computer and use it in GitHub Desktop.
Save dexterous/05761808a9e1f2e74c0181c48e41a46e to your computer and use it in GitHub Desktop.
Go provider-consumer as funcs
package main
import (
"context"
"log"
"runtime"
"sync"
"time"
)
func main() {
log.Println("Setting up...")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
ticker := time.NewTicker(2 * time.Second)
defer ticker.Stop()
q := producer(ctx, ticker.C)
var N int = runtime.GOMAXPROCS(0)
wg := &sync.WaitGroup{}
wg.Add(N)
for i := 1; i <= N; i++ {
go consumer(i, wg, q)
}
log.Println("Waiting...")
wg.Wait()
log.Println("... All done")
}
func producer[T any](ctx context.Context, supplier <-chan T) <-chan T {
log.Printf(" P -> initializing")
q := make(chan T)
go func() {
defer close(q)
defer log.Printf(" P -> done")
log.Printf(" P -> started")
for {
select {
case t, ok := <-supplier:
if !ok {
log.Printf(" P <- reports supplier closed")
return
}
log.Printf(" P -> %v", t)
q <- t
case <-ctx.Done():
log.Printf(" P -> %v", ctx.Err())
return
}
}
}()
return q
}
func consumer[T any](id int, wg *sync.WaitGroup, q <-chan T) {
defer wg.Done()
log.Printf(" W%d -- started", id)
for t := range q {
log.Printf(" W%d <- %v", id, t)
}
log.Printf(" W%d <- reports q closed", id)
log.Printf(" W%d -- done", id)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment