Description
All the currently provided channel abstractions in kotlinx.coroutines
are hot. The data is being produced regardless of the presence of subscriber. This is good for data sources and applications that are inherently hot, like incoming network and UI-events.
However, hot streams are not an ideal solution for cases where data stream is produced on demand. Consider, for example, the following simple code that produces ReceiveChannel<Int>
:
produce<Int> {
while (true) {
val x = computeNextValue()
send(x)
}
}
One obvious downside is the computeNextValue()
is invoked before send
, so even when receiver is not ready, the next value gets computed. Of course, it gets suspended in send
if there is no receiver, but it is not as lazy as you get with cold reactive Publisher/Observable/Flowable/Flux/Flow.
We need the abstraction for cold streams in kotlinx.coroutines
that is going to be just as lazy, computing data in "push" mode versus "pull" mode of hot channels that we have now.
There are the following related discussions:
- Reactor Kore - A Cross-Platform Non-Blocking Reactive Foundation reactor/reactor-core#979 (comment) describes preliminary performance test that indicates that "push" mode is much faster for same-thread cases.
- Introduce single-producer, single-consumer channel abstraction #113 (SPSC channels) seems to get superseded by the support of cold streams.