Channels - Professional¶
A channel API defines capacity, wake policy, ownership, closure, cancellation, fairness, and memory-order guarantees.
flowchart TD
Send --> Fast{Buffer or receiver ready?}
Fast -->|yes| Transfer
Fast -->|no| Park[Queue and park sender]
Receive --> Wake[Transfer and wake waiter]
Real internals¶
- Go
hchancontains a ring buffer, indices, a lock, andsendq/recvqwait lists represented bysudogrecords. - Tokio offers bounded
mpsc,broadcast,watch, andoneshot, each with different loss and ownership semantics. - Crossbeam channels use specialized array/list flavors and parking for Rust threads.
- Clojure
core.asyncimplements channels andalts!through state-machine transformations, not OS threads per task.
At 10x load, contention and parked tasks rise; at 100x, buffer memory and cancellation scans dominate. Dashboard send/receive tails, occupancy, waiter counts, drop or lag metrics, allocations, and leaked tasks. Runbooks need producer pause, channel drain, consumer restart, and data-loss accounting.
Design and operations checklist¶
- Pick semantics before selecting a library channel type.
- Bound capacity and define overload behavior.
- Give closure one owner and cancellation to every waiter.
- Test fairness, shutdown, and receiver disappearance.
- Benchmark against a mutex queue or direct call.
Further reading¶
- Go runtime source:
runtime/chan.go. - Tokio synchronization source and channel documentation.
- Vyukov, Bounded MPMC Queue.
Test yourself¶
- How do channel semantics change when values may be dropped?
- What wake policy balances throughput and fairness?
- When is a direct call or queue simpler than a channel?