Channel operations receive and send are performed eagerly, i.e., for
the current process, each application of the ioc loop greedily performs as
many yielding operations as possible, and will break only after encountering a
channel that causes the process to block.
Alternatively a process may be run lazily, by including the yield proc
expression, which forces control to be yielded back to the scheduler, and
re-enqueues the process at the end of the global run queue.
This may be useful, for example, within long-running loop structures, so as to cooperatively avoid causing starvation of other scheduled processes.
describe "Laziness:", ->
it "allows eager-to-lazy communication", async ->
nibble = go ->
src = chan.from [1..3]
yield receive proc ->
for i in [1..3]
value = yield receive src
yield proc
value
gobble = go ->
src = chan.from [1..9]
yield receive proc ->
for i in [1..9] then yield receive srcThe first process to finish should be gobble, even though nibble performs
fewer operations, because the receiving subprocess of nibble is lazy.
{value, channel} = yield from select nibble, gobble
assert.equal channel, gobbledescribe "chan.from", ->
it "correctly loads small arrays", ->
ch = chan.from [1..10]
assert.equal ch.buffer.queue.length, 10
it "correctly loads multi-cell size arrays", ->
ch = chan.from [1..72]
q = ch.buffer.queue
assert q?
assert.equal q.head._next._next, q.tail
assert.equal q.tail._prev._prev, q.head
assert.equal q.tail.array.length, 8