[rust-dev] RFC: New Rust channel proposal

Brian Anderson banderson at mozilla.com
Mon Jan 13 18:48:04 PST 2014


In light of the general consensus that unbounded channels are not so 
hot, here's a new proposal for how Rust's channels should operate. This 
is based on the following assumptions:

* Running out of memory is an awful failure mode for debugging.
* Choosing an appropriate bounded queue size is hard.
* Dealing with backpressure is hard.
* Most channels are not filled without bound.

This proposal has two facets: making the current channels appropriate 
for more use cases; adding additional channel types for specialized use 
cases. I'm still operating under the premise that there should be a 
"default" channel type that can be successfully used in most instances, 
and people should only need to pick something else when their message 
passing behavior calls for it. Not all of these recommendations are 
about resolving the unbounded channel debate.

# Changes to `Chan`

Firstly, let's combine `Chan` and `SharedChan`. This is partly to free 
up some of our complexity budget to add more channel types, and partly a 
concession to usability. A cloned channel will automatically upgrade 
itself to a multi-producer queue. This will add a small amount of 
overhead to various operations.

Secondly, in order to accommodate the very common case where a channel 
is used just once, we optimize the single-send use case to not allocate. 
Essentially, we store a single element directly in the shared state 
between the channel and port. This restores the `oneshot` functionality 
we lost in the last channel rewrite. Again, this will add a small amount 
of overhead to some operations, though possibly not above the overhead 
incurred by combining `Chan` and `SharedChan`.

Finally, my main suggestion about how to deal with OOM, let's put an 
arbitrary bound to the size of the queue on `Chan`. This isn't to say 
let's turn `Chan` into a bounded queue (which is difficult for 
implementation reasons), but instead that we add a feature that helps 
debug when you've actually chosen the wrong kind of channel because your 
producer sends without bound.

When you hit this bound the send will fail and you know that you need to 
think harder about the behavior of this particular channel. If you 
*really* want an unbounded channel then you can construct it with 
`Chan::unbounded`, otherwise you pick ...

# Synchronous and bounded channels

Let's add `SyncChan` which is a bounded multi-producer single-consumer 
queue backed by a ring buffer. This supports `send`, which blocks by 
default, and `try_send` which returns an enum representing whether the 
send succeeded, the channel is full, or the channel is closed (the last 
two cases returning the message). In the special case where the channel 
bound is 0, we don't use a ringbuffer and just do a rendezvousing send 
and recieve. The default bound is 0.

Comments?

Regards,
Brian


More information about the Rust-dev mailing list