ChannelA CSP-style channel for passing values between tasks. Channel.new is an unbuffered rendezvous -- a send parks until a receiver takes the value; Channel.buffered:n queues up to n values before sends park. close ends the conversation: further sends raise, receives drain the buffer then answer nil, and each: ends.
var ch = Channel.new; Task.spawn:{ ch.send:42 }; ch.receive "* -> 42
A channel that buffers up to n values before sends park (0 is unbuffered).
var ch = Channel.buffered:2; ch.send:1; ch.send:2; ch.close; #( ch.receive ch.receive ) "* -> #(1 2)
An unbuffered (rendezvous) channel: every send waits for its receiver.
The buffer capacity; 0 for an unbuffered (rendezvous) channel.
Close the channel (idempotent); answers nil. Parked and future sends raise; buffered values remain receivable; a drained receive answers nil and each: ends.
True once the channel has been closed.
How many values are currently buffered (sent but not yet received).
Run the block on each received value until the channel is closed and drained, parking between values; answers nil.
var ch = Channel.buffered:3; ch.send:1; ch.send:2; ch.close; var sum = 0; ch.each:{ |v| sum = sum + v }; sum "* -> 3
The next value, parking until one is available -- buffered values first (FIFO), else directly from a parked sender. On a closed, drained channel answers nil.
Send a value: hand it to a waiting receiver, else buffer it if there is room, else park until a receiver takes it. Raises on a closed channel. Answers nil.