On 12/30/13 8:40 PM, Christian Ohler wrote:
Example: Even if the scheduling is perfectly fair and assigns the same number of cycles to a producing task and the corresponding consuming task, the producer can still outrun the consumer if producing a message takes fewer cycles than consuming one, leading to memory exhaustion if the channel is unbounded.
Unless there's some kind of protocol.
Vectors don't have such problems. We can construct programs where the size of a vector becomes dependent on scheduling or other nondeterministic runtime behavior; but channels are inherently tied to inter-task communication and scheduling, and vectors are not.
But the size of a vector can be dependent on user input and various other things pretty easily as well. I think unbounded channels are no worse than vectors.
For example, processing might happen in stages, and data flows "left to right", where tasks are either ready to receive any message from the left, or blocked sending a specific message to the right. Since there is never a mismatch in what the receiver expects and what the sender sends, nor is there a cycle in the blocking sends, there won't be deadlocks.
I gave an example earlier in which deadlocks can happen.
I haven't thought this through completely, and don’t have a formal argument, but I am finding these patterns in systems that I’m working on. Perhaps this is analogous to how we are generally not worried that language features like unrestricted function calls and higher-order functions will make it difficult to avoid infinite recursion: Programmers have a mental model of how their system is layered, and they know that calls generally go from higher layers into lower layers, with few exceptions that they structure in ways that avoid infinite recursion.
But this argument applies equally well to unbounded channels, in that you can use them safely as long as you think through the way in which you're using them. For example, Servo is architected in such a way so that the channels will never overflow, due to the acknowledgement pattern among other forms of backpressure.
It is clear that you can implement one on top of the other in both directions. The question is how difficult it is to do so, and how much performance you lose.
(4) Servo should implement web semantics without pushing them as requirements into libstd. Servo needs an unbounded UI event queue, but that doesn't mean libstd needs to provide unbounded channels. Mapping the UI event queue directly to a libstd channel may be a neat match right now, but it seems prudent to leave servo product features decoupled from libstd features and being prepared to introduce intermediate layers, since servo's product requirements can shift.
Servo is not the only thing that wants unbounded channels. There have been other examples of applications that need unbounded channels on this very list.
I'm not particularly interested in sacrificing performance by not implementing one or the other in libstd. I think it's clear we need both forms of channels, and they should be first-class primitives.
Patrick _______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
