This module contains the implementation of Std.Channel
. Std.Channel
is a multi-producer
multi-consumer FIFO channel that offers both bounded and unbounded buffering as well as synchronous
and asynchronous APIs.
Additionally Std.CloseableChannel
is provided in case closing the channel is of interest.
The two are distinct as the non closable Std.Channel
can never throw errors which makes
for cleaner code.
Errors that may be thrown while interacting with the channel API.
Equations
Equations
Equations
- One or more equations did not get rendered due to their size.
A multi-producer multi-consumer FIFO channel that offers both bounded and unbounded buffering
and an asynchronous API, to switch into synchronous mode use CloseableChannel.sync
.
Additionally Std.CloseableChannel
can be closed if necessary, unlike Std.Channel
.
This introduces a need for error handling in some cases, thus it is usually easier to use
Std.Channel
if applicable.
Equations
Instances For
A multi-producer multi-consumer FIFO channel that offers both bounded and unbounded buffering and a synchronous API. This type acts as a convenient layer to use a channel in a blocking fashion and is not actually different from the original channel.
Additionally Std.CloseableChannel.Sync
can be closed if necessary, unlike Std.Channel.Sync
.
This introduces the need to handle errors in some cases, thus it is usually easier to use
Std.Channel
if applicable.
Equations
Create a new channel, if:
capacity
isnone
it will be unbounded (the default)capacity
issome 0
it will always force a rendezvous between sender and receivercapacity
issome n
withn > 0
it will use a buffer of sizen
and begin blocking once it is filled
Equations
- Std.CloseableChannel.new = do let __do_lift ← Std.CloseableChannel.Unbounded.new✝ pure (Std.CloseableChannel.Flavors.unbounded✝ __do_lift)
- Std.CloseableChannel.new (some 0) = do let __do_lift ← Std.CloseableChannel.Zero.new✝ pure (Std.CloseableChannel.Flavors.zero✝ __do_lift)
- Std.CloseableChannel.new (some n.succ) = do let __do_lift ← Std.CloseableChannel.Bounded.new✝ (n + 1) ⋯ pure (Std.CloseableChannel.Flavors.bounded✝ __do_lift)
Try to send a value to the channel, if this can be completed right away without blocking return
true
, otherwise don't send the value and return false
.
Equations
- Std.CloseableChannel.trySend (Std.CloseableChannel.Flavors.unbounded✝ ch_2) v = ch_2.trySend v
- Std.CloseableChannel.trySend (Std.CloseableChannel.Flavors.zero✝ ch_2) v = ch_2.trySend v
- Std.CloseableChannel.trySend (Std.CloseableChannel.Flavors.bounded✝ ch_2) v = ch_2.trySend v
Send a value through the channel, returning a task that will resolve once the transmission could be
completed. Note that the task may resolve to Except.error
if the channel was closed before it
could be completed.
Equations
- Std.CloseableChannel.send (Std.CloseableChannel.Flavors.unbounded✝ ch_2) v = ch_2.send v
- Std.CloseableChannel.send (Std.CloseableChannel.Flavors.zero✝ ch_2) v = ch_2.send v
- Std.CloseableChannel.send (Std.CloseableChannel.Flavors.bounded✝ ch_2) v = ch_2.send v
Closes the channel, returns Except.ok
when called the first time, otherwise Except.error
.
When a channel is closed:
- no new values can be sent successfully anymore
- all blocked consumers are resolved to
none
(as no new messages can be sent they will never resolve) - if there are already values waiting to be received they can still be received by subsequent
recv
calls
Equations
Return true
if the channel is closed.
Try to receive a value from the channel, if this can be completed right away without blocking return
some value
, otherwise return none
.
Receive a value from the channel, returning a task that will resolve once the transmission could be
completed. Note that the task may resolve to none
if the channel was closed before it could be
completed.
Equations
Creates a Selector
that resolves once ch
has data available and provides that that data.
In particular if ch
is closed while waiting on this Selector
and no data is available already
this will resolve to none
.
Equations
ch.forAsync f
calls f
for every message received on ch
.
Note that if this function is called twice, each message will only arrive at exactly one invocation.
This function is a no-op and just a convenient way to expose the synchronous API of the channel.
Create a new channel, if:
capacity
isnone
it will be unbounded (the default)capacity
issome 0
it will always force a rendezvous between sender and receivercapacity
issome n
withn > 0
it will use a buffer of sizen
and begin blocking once it is filled
Equations
- Std.CloseableChannel.Sync.new capacity = Std.CloseableChannel.new capacity
Try to send a value to the channel, if this can be completed right away without blocking return
true
, otherwise don't send the value and return false
.
Equations
- ch.trySend v = Std.CloseableChannel.trySend ch v
Send a value through the channel, blocking until the transmission could be completed. Note that this function may throw an error when trying to send to an already closed channel.
Equations
- ch.send v = do let __do_lift ← liftM (Std.CloseableChannel.send ch v) let __do_lift ← liftM (IO.wait __do_lift) EIO.ofExcept __do_lift
Closes the channel, returns Except.ok
when called the first time, otherwise Except.error
.
When a channel is closed:
- no new values can be sent successfully anymore
- all blocked consumers are resolved to
none
(as no new messages can be sent they will never resolve) - if there are already values waiting to be received they can still be received by subsequent
recv
calls
Equations
- ch.close = Std.CloseableChannel.close ch
Return true
if the channel is closed.
Equations
Try to receive a value from the channel, if this can be completed right away without blocking return
some value
, otherwise return none
.
Equations
Receive a value from the channel, blocking until the transmission could be completed. Note that the
return value may be none
if the channel was closed before it could be completed.
Equations
- ch.recv = do let __do_lift ← Std.CloseableChannel.recv ch IO.wait __do_lift
for msg in ch.sync do ...
receives all messages in the channel until it is closed.
Equations
- One or more equations did not get rendered due to their size.
A multi-producer multi-consumer FIFO channel that offers both bounded and unbounded buffering
and an asynchronous API, to switch into synchronous mode use Channel.sync
.
If a channel needs to be closed to indicate some sort of completion event use Std.CloseableChannel
instead. Note that Std.CloseableChannel
introduces a need for error handling in some cases, thus
Std.Channel
is usually easier to use if applicable.
- inner : Std.CloseableChannel α
Instances For
A multi-producer multi-consumer FIFO channel that offers both bounded and unbounded buffering and a synchronous API. This type acts as a convenient layer to use a channel in a blocking fashion and is not actually different from the original channel.
If a channel needs to be closed to indicate some sort of completion event use
Std.CloseableChannel.Sync
instead. Note that Std.CloseableChannel.Sync
introduces a need for error
handling in some cases, thus Std.Channel.Sync
is usually easier to use if applicable.
Equations
Create a new channel, if:
capacity
isnone
it will be unbounded (the default)capacity
issome 0
it will always force a rendezvous between sender and receivercapacity
issome n
withn > 0
it will use a buffer of sizen
and begin blocking once it is filled
Equations
- Std.Channel.new capacity = do let __do_lift ← Std.CloseableChannel.new capacity pure { inner := __do_lift }
Try to send a value to the channel, if this can be completed right away without blocking return
true
, otherwise don't send the value and return false
.
Equations
- ch.trySend v = (Std.Channel.inner✝ ch).trySend v
Try to receive a value from the channel, if this can be completed right away without blocking return
some value
, otherwise return none
.
Equations
- ch.tryRecv = (Std.Channel.inner✝ ch).tryRecv
Receive a value from the channel, returning a task that will resolve once the transmission could be
completed. Note that the task may resolve to none
if the channel was closed before it could be
completed.
Equations
- One or more equations did not get rendered due to their size.
Creates a Selector
that resolves once ch
has data available and provides that that data.
Equations
- One or more equations did not get rendered due to their size.
ch.forAsync f
calls f
for every message received on ch
.
Note that if this function is called twice, each message will only arrive at exactly one invocation.
Create a new channel, if:
capacity
isnone
it will be unbounded (the default)capacity
issome 0
it will always force a rendezvous between sender and receivercapacity
issome n
withn > 0
it will use a buffer of sizen
and begin blocking once it is filled
Equations
- Std.Channel.Sync.new capacity = Std.Channel.new capacity
Try to send a value to the channel, if this can be completed right away without blocking return
true
, otherwise don't send the value and return false
.
Equations
- ch.trySend v = Std.Channel.trySend ch v
Send a value through the channel, blocking until the transmission could be completed.
Equations
- ch.send v = do let __do_lift ← Std.Channel.send ch v IO.wait __do_lift
Try to receive a value from the channel, if this can be completed right away without blocking return
some value
, otherwise return none
.
Equations
- ch.tryRecv = Std.Channel.tryRecv ch
Receive a value from the channel, blocking until the transmission could be completed.
Equations
- ch.recv = do let __do_lift ← Std.Channel.recv ch IO.wait __do_lift
for msg in ch.sync do ...
receives all messages in the channel until it is closed.
Equations
- One or more equations did not get rendered due to their size.