package main
import (
"context"
"fmt"
"time"
)
// ❌ Leak risk — if no one ever receives, this goroutine lives forever
func leakyProducer(ch chan<- int) {
ch <- 42 // blocks if buffer is full / no receiver
}
// ✓ Safe — give the goroutine an escape via the context
func safeProducer(ctx context.Context, ch chan<- int) {
select {
case ch <- 42:
// sent successfully
case <-ctx.Done():
return // exit on cancellation
}
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
ch := make(chan int) // unbuffered — no receiver yet
go safeProducer(ctx, ch)
time.Sleep(200 * time.Millisecond)
fmt.Println("producer exited cleanly via ctx")
// Run with `go test -race` to catch leaks; also try `runtime.NumGoroutine()`.
}
Create a free account and build your private vault. Share publicly whenever you want.