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 src
The 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, gobble
describe "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