@@ -141,7 +141,8 @@ Let us rewrite this code using [publish] coroutine builder from `kotlinx-corouti
141141instead of [ produce] from ` kotlinx-coroutines-core ` module. The code stays the same,
142142but where ` source ` used to have [ ReceiveChannel] type, it now has reactive streams
143143[ Publisher] ( https://www.reactive-streams.org/reactive-streams-1.0.0-javadoc/org/reactivestreams/Publisher.html )
144- type.
144+ type, where [ consumeEach] was used to _ consume_ elements from the channel,
145+ now [ collect] [ org.reactivestreams.Publisher.collect ] is used to _ collect_ elements from the publisher.
145146
146147<!-- - INCLUDE
147148import kotlinx.coroutines.*
@@ -194,15 +195,15 @@ Begin
194195
195196This example highlights the key difference between a reactive stream and a channel. A reactive stream is a higher-order
196197functional concept. While the channel _ is_ a stream of elements, the reactive stream defines a recipe on how the stream of
197- elements is produced. It becomes the actual stream of elements on _ subscription _ . Each subscriber may receive the same or
198+ elements is produced. It becomes the actual stream of elements when _ collected _ . Each collector may receive the same or
198199a different stream of elements, depending on how the corresponding implementation of ` Publisher ` works.
199200
200- The [ publish] coroutine builder, that is used in the above example, launches a fresh coroutine on each subscription.
201- Every [ Publisher. collect] [ org.reactivestreams.Publisher.collect ] invocation creates a fresh subscription .
201+ The [ publish] coroutine builder, that is used in the above example, does not launch a coroutine,
202+ but every [ collect] [ org.reactivestreams.Publisher.collect ] invocation launches a coroutine .
202203We have two of them in this code and that is why we see "Begin" printed twice.
203204
204- In Rx lingo this is called a _ cold_ publisher. Many standard Rx operators produce cold streams, too. We can iterate
205- over them from a coroutine, and every subscription produces the same stream of elements.
205+ In Rx lingo this is called a _ cold_ publisher. Many standard Rx operators produce cold streams, too. We can collect
206+ them from a coroutine, and every collector gets the same stream of elements.
206207
207208** WARNING** : It is planned that in the future a second invocation of ` consumeEach ` method
208209on an channel that is already being consumed is going to fail fast, that is
@@ -217,10 +218,10 @@ method with it.
217218
218219### Subscription and cancellation
219220
220- An example in the previous section uses ` source.collect { ... } ` snippet to open a subscription
221- and receive all the elements from it. If we need more control on how what to do with
222- the elements that are being received from the channel, we can use [ Publisher.collect ] [ org.reactivestreams.Publisher.collect ]
223- as shown in the following example :
221+ An example in the previous section uses ` source.collect { ... } ` to collect all elements.
222+ Instead of collecting elements, we can open a channel using [ openSubscription ] [ org.reactivestreams.Publisher.openSubscription ]
223+ and iterate over it, so that we have more finer-grained control on our iteration,
224+ for example using ` break ` , as shown below :
224225
225226<!-- - INCLUDE
226227import io.reactivex.*
@@ -259,17 +260,16 @@ Finally
259260```
260261
261262<!-- - TEST -->
262-
263+
263264With an explicit ` openSubscription ` we should [ cancel] [ ReceiveChannel.cancel ] the corresponding
264- subscription to unsubscribe from the source. There is no need to invoke ` cancel ` explicitly -- under the hood
265- ` consume ` does that for us.
265+ subscription to unsubscribe from the source, but there is no need to call ` cancel ` explicitly -- under the hood
266+ [ consume] does that for us.
266267The installed
267268[ doFinally] ( https://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Flowable.html#doFinally(io.reactivex.functions.Action) )
268269listener prints "Finally" to confirm that the subscription is actually being closed. Note that "OnComplete"
269270is never printed because we did not consume all of the elements.
270271
271- We do not need to use an explicit ` cancel ` either if iteration is performed over all the items that are emitted
272- by the publisher, because it is being cancelled automatically by ` collect ` :
272+ We do not need to use an explicit ` cancel ` either if we ` collect ` all the elements:
273273
274274<!-- - INCLUDE
275275import io.reactivex.*
@@ -284,7 +284,7 @@ fun main() = runBlocking<Unit> {
284284 .doOnSubscribe { println (" OnSubscribe" ) } // provide some insight
285285 .doOnComplete { println (" OnComplete" ) } // ...
286286 .doFinally { println (" Finally" ) } // ... into what's going on
287- // iterate over the source fully
287+ // collect the source fully
288288 source.collect { println (it) }
289289}
290290```
@@ -684,8 +684,8 @@ fun <T, U> Publisher<T>.takeUntil(context: CoroutineContext, other: Publisher<U>
684684 other.openSubscription().consume { // explicitly open channel to Publisher<U>
685685 val other = this
686686 whileSelect {
687- other.onReceive { false } // bail out on any received element from `other`
688- current.onReceive { send(it); true } // resend element from this channel and continue
687+ other.onReceive { false } // bail out on any received element from `other`
688+ current.onReceive { send(it); true } // resend element from this channel and continue
689689 }
690690 }
691691 }
@@ -1068,6 +1068,7 @@ coroutines for complex pipelines with fan-in and fan-out between multiple worker
10681068[ consumeEach ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/consume-each.html
10691069[ ReceiveChannel ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-receive-channel/index.html
10701070[ ReceiveChannel.cancel ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-receive-channel/cancel.html
1071+ [ consume ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/consume.html
10711072[ SendChannel.send ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-send-channel/send.html
10721073[ BroadcastChannel ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-broadcast-channel/index.html
10731074[ ConflatedBroadcastChannel ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-conflated-broadcast-channel/index.html
@@ -1078,6 +1079,7 @@ coroutines for complex pipelines with fan-in and fan-out between multiple worker
10781079<!-- - INDEX kotlinx.coroutines.reactive -->
10791080[ publish ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-reactive/kotlinx.coroutines.reactive/kotlinx.coroutines.-coroutine-scope/publish.html
10801081[ org.reactivestreams.Publisher.collect ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-reactive/kotlinx.coroutines.reactive/org.reactivestreams.-publisher/collect.html
1082+ [ org.reactivestreams.Publisher.openSubscription ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-reactive/kotlinx.coroutines.reactive/org.reactivestreams.-publisher/open-subscription.html
10811083<!-- - MODULE kotlinx-coroutines-rx2 -->
10821084<!-- - INDEX kotlinx.coroutines.rx2 -->
10831085[ rxFlowable ] : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-rx2/kotlinx.coroutines.rx2/kotlinx.coroutines.-coroutine-scope/rx-flowable.html
0 commit comments