Awaits for the specified number of consumers to be connected.
Awaits for the specified number of consumers to be connected.
This is an utility to ensure that a certain number of consumers are connected before we start emitting events.
is a number indicating the number of consumers that need to be connected before the returned task completes
a task that will complete only after the required number of consumers are observed as being connected to the channel
Closes the communication channel with a message that will be visible to all current and future consumers.
Closes the communication channel with a message that will be visible to all current and future consumers.
Note that if multiple halt
events happen, then only the first one
will be taken into account, all other halt
messages are ignored.
Publishes an event on the channel.
Publishes an event on the channel.
Contract:
true
in case the message was pushed in the internal buffer
or false
in case the channel was halted and cannot receive any
more events, in which case the producer's loop should terminateExample:
import cats.implicits._ import cats.effect.Async def range[F[_]](channel: ProducerF[F, Int, Int], from: Int, until: Int) (implicit F: Async[F]): F[Unit] = { if (from < until) { if (from + 1 < until) channel.push(from).flatMap { case true => // keep going range(channel, from + 1, until) case false => // channel was halted by another producer loop, so stopping F.unit } else // we are done, publish the final event channel.halt(from + 1).as(()) } else { F.unit // invalid range } }
is the message to publish
true
in case the message was published successfully, or
false
in case the channel was halted by another producer
Publishes multiple events on the channel.
Publishes multiple events on the channel.
Contract:
true
in case the whole sequence was pushed in the internal
b or false
in case the channel was halted and cannot receive any
more events, in which case the producer's loop should terminateNote: implementations may try to push events one by one. This is not
an atomic operation. In case of concurrent producers, there's absolutely
no guarantee for the order of messages coming from multiple producers.
Also in case the channel is halted (and the resulting task returns false
),
the outcome can be that the sequence gets published partially.
import cats.implicits._ import cats.effect.Async def range[F[_]](channel: ProducerF[F, Int, Int], from: Int, until: Int) (implicit F: Async[F]): F[Unit] = { if (from < until) { val to = until - 1 channel.pushMany(Range(from, to)).flatMap { case true => channel.halt(to).as(()) // final event case false => // channel was halted by a concurrent producer, so stop F.unit } } else { F.unit // invalid range } }
is the sequence of messages to publish on the channel
true
in case the message was published successfully, or
false
in case the channel was halted by another producer
A simple interface that models the producer side of a producer-consumer communication channel.
In a producer-consumer communication channel we've got these concerns to take care of:
The
ProducerF
interface takes care of these concerns via:F[Boolean]
result, which should returntrue
for as long as the channel wasn't halted, so further events can be pushed; these tasks also block (asynchronously) when internal buffers are full, so back-pressure concerns are handled automaticallyCurrently implemented by ConcurrentChannel.