282. mpsc::sync_channel — A Channel That Pushes Back When the Consumer Falls Behind
mpsc::channel() never says no: a fast producer and a slow consumer means the queue — and your memory — grows without bound. sync_channel(n) caps the queue and makes the producer wait.
Bite 281 used mpsc::channel() to collect results from workers. Its buffer is unbounded — send always succeeds immediately, no matter how far behind the receiver is:
| |
If the consumer parses files, writes to a database, or talks to a network, the producer can outrun it by orders of magnitude. Nothing crashes; the process just eats memory until something else does.
mpsc::sync_channel(n) creates a bounded channel: at most n messages queued. Once full, send blocks until the receiver catches up — that’s backpressure. try_send gives you the non-blocking version that reports the problem instead:
| |
Note the error hands the value back — TrySendError::Full(3) — so nothing is lost; you can retry, drop it, or spill it elsewhere.
The odd-looking special case is sync_channel(0): a rendezvous channel with no buffer at all. Every send blocks until a recv is ready to take the value, so each handoff is also a synchronization point between the two threads:
| |
Rule of thumb: channel() when producers must never wait, sync_channel(n) when the consumer sets the pace. If you’d rather drop data than slow the producer, try_send makes that an explicit decision instead of an accidental out-of-memory.