Channel closing
Close channels only to signal no more sends; ownership of closing must be singular and obvious.
Canonical guidance
- the sending side closes when it knows no more values will arrive
- receivers do not close channels they do not own
- close channels for completion signals, not acknowledgments
Use when
- producer completion
- pipeline shutdown
- fan-out workers consuming a finite stream
Avoid
- multiple senders racing to close the same channel
- closing from the receive side
- treating
closeas a generic broadcast for unrelated state changes
Preferred pattern
out := make(chan Item)
go func() {
defer close(out)
for _, item := range items {
out <- item
}
}()
Anti-pattern
- adding
recoveraroundclose(ch)because ownership is unclear
Explanation: This anti-pattern is tempting because it suppresses panics, but it hides a lifecycle bug instead of fixing it.
Why
- channel shutdown is simple only when channel ownership is simple
Related pages
Sources
- The Go Programming Language Specification - Go Team
- Go Concurrency Patterns: Pipelines and cancellation - Sameer Ajmani