Skip to content

Commit c961fb6

Browse files
committed
Tweaked prose in coroutines-guide-reactive a bit (and reknit)
1 parent 0685dc4 commit c961fb6

File tree

4 files changed

+24
-22
lines changed

4 files changed

+24
-22
lines changed

reactive/coroutines-guide-reactive.md

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ Let us rewrite this code using [publish] coroutine builder from `kotlinx-corouti
141141
instead of [produce] from `kotlinx-coroutines-core` module. The code stays the same,
142142
but 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
147148
import kotlinx.coroutines.*
@@ -194,15 +195,15 @@ Begin
194195

195196
This example highlights the key difference between a reactive stream and a channel. A reactive stream is a higher-order
196197
functional 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
198199
a 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.
202203
We 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
208209
on 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
226227
import io.reactivex.*
@@ -259,17 +260,16 @@ Finally
259260
```
260261

261262
<!--- TEST -->
262-
263+
263264
With 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.
266267
The installed
267268
[doFinally](https://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Flowable.html#doFinally(io.reactivex.functions.Action))
268269
listener prints "Finally" to confirm that the subscription is actually being closed. Note that "OnComplete"
269270
is 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
275275
import 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

reactive/kotlinx-coroutines-rx2/test/guide/example-reactive-basic-04.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ fun main() = runBlocking<Unit> {
1515
.doOnSubscribe { println("OnSubscribe") } // provide some insight
1616
.doOnComplete { println("OnComplete") } // ...
1717
.doFinally { println("Finally") } // ... into what's going on
18-
// iterate over the source fully
18+
// collect the source fully
1919
source.collect { println(it) }
2020
}

reactive/kotlinx-coroutines-rx2/test/guide/example-reactive-operators-02.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ fun <T, R> Publisher<T>.fusedFilterMap(
1515
predicate: (T) -> Boolean, // the filter predicate
1616
mapper: (T) -> R // the mapper function
1717
) = GlobalScope.publish<R>(context) {
18-
collect { // consume the source stream
18+
collect { // collect the source stream
1919
if (predicate(it)) // filter part
2020
send(mapper(it)) // map part
2121
}

reactive/kotlinx-coroutines-rx2/test/guide/example-reactive-operators-03.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ fun <T, U> Publisher<T>.takeUntil(context: CoroutineContext, other: Publisher<U>
1818
other.openSubscription().consume { // explicitly open channel to Publisher<U>
1919
val other = this
2020
whileSelect {
21-
other.onReceive { false } // bail out on any received element from `other`
22-
current.onReceive { send(it); true } // resend element from this channel and continue
21+
other.onReceive { false } // bail out on any received element from `other`
22+
current.onReceive { send(it); true } // resend element from this channel and continue
2323
}
2424
}
2525
}

0 commit comments

Comments
 (0)