channels
nimony/lib/std/channels.nim
Typed channels (nim-lang/nimony#2635): copyable Sender[T]/Receiver[T] ends, over an in-process ring (channel[T]) or over any std/streamio stream (sender[T], receiver[T]). Waiting parks the task, it does not block a thread.
.. code-block:: nim let (r, s) = channelJob submit(delay(worker(r))) discard s.send Job(id: 1)
A Sender[T] and a Receiver[T] are copyable; all copies share ONE end, a Writer or Reader, so a stream never has more than one of each and its lifecycle stays that of a connection: the last copy gone is the end gone.
type Sender = object e: ref SendEndObj
type Receiver = object e: ref RecvEndObj
proc channel(capacity: int64): tuple[Receiver[T], Sender[T]]A channel for up to
capacityvalues. AnyTworks: a value moves as its bytes, and what it points to stays where it is. The ring underneath is never handed out, so nothing can write those pointers to a file.proc sender(w: sink Writer): Sender[T]Values of
Tover anyWriter, as their bytes. Between machines the layout and the byte order must match.senddoes not flush; seeflush.proc receiver(r: sink Reader): Receiver[T]Values of
Tfrom anyReader. A message cut short by the end of the data raisesProtocolError.proc send(s: Sender[T]; x: sink T): boolParks while the channel is full. False when no receiver is left;
xis consumed either way. Raises what theWriterunderneath raises.proc recv(r: Receiver[T]; dest: var T): boolParks while the channel is empty. False when no sender is left and nothing is buffered;
destis then untouched.proc tryRecv(r: Receiver[T]; dest: var T): boolOne value if one is already waiting; false when the channel is empty, or every sender is gone. Never parks, so a task can drain what is there, do something with the batch — put it on a socket with one flush, say — and only then
recv.proc flush(s: Sender[T])For a sender over a buffered
Writer: everything sent goes out. A channel's own sends need no flush.