Non-Blocking Channel Operations
Use select with a default case to attempt a channel send or receive without blocking.
By adding a default case to a select, a channel operation becomes non-blocking - if no channel is ready the default runs immediately, and the goroutine is never suspended.
Try to receive from messages. If no message is waiting, fall through to default without blocking.
package main
import "fmt"
func main() {
messages := make(chan string)
signals := make(chan bool)
// non-blocking receive
select {
case msg := <-messages:
fmt.Println("received message", msg)
default:
fmt.Println("no message received")
}
// non-blocking send
msg := "hi"
select {
case messages <- msg:
fmt.Println("sent message", msg)
default:
fmt.Println("no message sent")
}
// multi-way non-blocking
select {
case msg := <-messages:
fmt.Println("received message", msg)
case sig := <-signals:
fmt.Println("received signal", sig)
default:
fmt.Println("no activity")
}
}The try-send pattern is a common idiom for metric collection and event streaming - drop the event if the consumer is slow rather than blocking the producer:
func recordEvent(ch chan<- Event, e Event) {
select {
case ch <- e:
// sent
default:
// consumer is slow; drop rather than block
droppedEvents.Add(1)
}
}Non-blocking receive is useful for draining a buffered channel without risk of blocking if it is already empty:
func drain(ch <-chan int) []int {
var results []int
for {
select {
case v := <-ch:
results = append(results, v)
default:
return results // channel empty
}
}
}In production
The try-send pattern (select { case ch <- v: default: }) lets a producer drop work rather than block when the consumer is slow. This is appropriate for metric collection, event streaming, or sampling where dropping under load is acceptable. For work that must not be dropped, use a bounded buffer and propagate backpressure to the caller instead - a full channel should be a signal to slow down production, not a trigger to silently discard data.
Enjoyed this? Get more essays on software craft delivered to your inbox.
Subscribe free