Skip to content

Commit e8e9f00

Browse files
Inegoelizarov
authored andcommitted
Fix typos and reword some phrases
1 parent 7699a20 commit e8e9f00

File tree

1 file changed

+56
-56
lines changed

1 file changed

+56
-56
lines changed

reactive/coroutines-guide-reactive.md

+56-56
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ class GuideReactiveTest : ReactiveTestBase() {
2020

2121
# Guide to reactive streams with coroutines
2222

23-
This guide explains key differences between Kotlin coroutines and reactive streams and shows
24-
how they can be used together for greater good. Prior familiarity with basic coroutine concepts
23+
This guide explains the key differences between Kotlin coroutines and reactive streams and shows
24+
how they can be used together for the greater good. Prior familiarity with the basic coroutine concepts
2525
that are covered in [Guide to kotlinx.coroutines](../docs/coroutines-guide.md) is not required,
2626
but is a big plus. If you are familiar with reactive streams, you may find this guide
2727
a better introduction into the world of coroutines.
@@ -130,18 +130,18 @@ Again:
130130

131131
<!--- TEST -->
132132

133-
Notice, how "Begin" line was printed just once, because [produce] _coroutine builder_, when it is executed,
133+
Notice how the "Begin" line was printed just once, because the [produce] _coroutine builder_, when it is executed,
134134
launches one coroutine to produce a stream of elements. All the produced elements are consumed
135135
with [ReceiveChannel.consumeEach][consumeEach]
136136
extension function. There is no way to receive the elements from this
137-
channel again. The channel is closed when the producer coroutine is over and the attempt to receive
137+
channel again. The channel is closed when the producer coroutine is over and an attempt to receive
138138
from it again cannot receive anything.
139139

140-
Let us rewrite this code using [publish] coroutine builder from `kotlinx-coroutines-reactive` module
140+
Let us rewrite this code using the [publish] coroutine builder from `kotlinx-coroutines-reactive` module
141141
instead of [produce] from `kotlinx-coroutines-core` module. The code stays the same,
142-
but where `source` used to have [ReceiveChannel] type, it now has reactive streams
142+
but where `source` used to have the [ReceiveChannel] type, it now has the reactive streams'
143143
[Publisher](https://www.reactive-streams.org/reactive-streams-1.0.0-javadoc/org/reactivestreams/Publisher.html)
144-
type, where [consumeEach] was used to _consume_ elements from the channel,
144+
type, and where [consumeEach] was used to _consume_ elements from the channel,
145145
now [collect][org.reactivestreams.Publisher.collect] is used to _collect_ elements from the publisher.
146146

147147
<!--- INCLUDE
@@ -198,11 +198,11 @@ functional concept. While the channel _is_ a stream of elements, the reactive st
198198
elements is produced. It becomes the actual stream of elements when _collected_. Each collector may receive the same or
199199
a different stream of elements, depending on how the corresponding implementation of `Publisher` works.
200200

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.
203-
We have two of them in this code and that is why we see "Begin" printed twice.
201+
The [publish] coroutine builder used in the above example does not launch a coroutine,
202+
but every [collect][org.reactivestreams.Publisher.collect] invocation does.
203+
There are two of them here and that is why we see "Begin" printed twice.
204204

205-
In Rx lingo this is called a _cold_ publisher. Many standard Rx operators produce cold streams, too. We can collect
205+
In Rx lingo, this kind of publisher is called _cold_. Many standard Rx operators produce cold streams, too. We can collect
206206
them from a coroutine, and every collector gets the same stream of elements.
207207

208208
> Note that we can replicate the same behaviour that we saw with channels by using Rx
@@ -212,10 +212,10 @@ method with it.
212212

213213
### Subscription and cancellation
214214

215-
An example in the previous section uses `source.collect { ... }` to collect all elements.
216-
Instead of collecting elements, we can open a channel using [openSubscription][org.reactivestreams.Publisher.openSubscription]
217-
and iterate over it, so that we have more finer-grained control on our iteration,
218-
for example using `break`, as shown below:
215+
In the second example from the previous section, `source.collect { ... }` was used to collect all elements.
216+
Instead, we can open a channel using [openSubscription][org.reactivestreams.Publisher.openSubscription]
217+
and iterate over it. In this way, we can have finer-grained control over our iteration
218+
(using `break`, for example), as shown below:
219219

220220
<!--- INCLUDE
221221
import io.reactivex.*
@@ -256,8 +256,8 @@ Finally
256256
<!--- TEST -->
257257

258258
With an explicit `openSubscription` we should [cancel][ReceiveChannel.cancel] the corresponding
259-
subscription to unsubscribe from the source, but there is no need to call `cancel` explicitly -- under the hood
260-
[consume] does that for us.
259+
subscription to unsubscribe from the source, but there is no need to call `cancel` explicitly --
260+
[consume] does that for us under the hood.
261261
The installed
262262
[doFinally](https://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Flowable.html#doFinally(io.reactivex.functions.Action))
263263
listener prints "Finally" to confirm that the subscription is actually being closed. Note that "OnComplete"
@@ -300,9 +300,9 @@ Finally
300300

301301
<!--- TEST -->
302302

303-
Notice, how "OnComplete" and "Finally" are printed before the last element "5". It happens because our `main` function in this
304-
example is a coroutine that we start with [runBlocking] coroutine builder.
305-
Our main coroutine receives on the flowable using `source.collect { ... }` expression.
303+
Notice how "OnComplete" and "Finally" are printed before the last element "5". It happens because our `main` function in this
304+
example is a coroutine that we start with the [runBlocking] coroutine builder.
305+
Our main coroutine receives on the flowable using the `source.collect { ... }` expression.
306306
The main coroutine is _suspended_ while it waits for the source to emit an item.
307307
When the last item is emitted by `Flowable.range(1, 5)` it
308308
_resumes_ the main coroutine, which gets dispatched onto the main thread to print this
@@ -313,14 +313,14 @@ _resumes_ the main coroutine, which gets dispatched onto the main thread to prin
313313
Backpressure is one of the most interesting and complex aspects of reactive streams. Coroutines can
314314
_suspend_ and they provide a natural answer to handling backpressure.
315315

316-
In Rx Java 2.x a backpressure-capable class is called
316+
In Rx Java 2.x, the backpressure-capable class is called
317317
[Flowable](https://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Flowable.html).
318-
In the following example we use [rxFlowable] coroutine builder from `kotlinx-coroutines-rx2` module to define a
318+
In the following example, we use [rxFlowable] coroutine builder from `kotlinx-coroutines-rx2` module to define a
319319
flowable that sends three integers from 1 to 3.
320-
It prints a message to the output before invocation of
320+
It prints a message to the output before invocation of the
321321
suspending [send][SendChannel.send] function, so that we can study how it operates.
322322

323-
The integers are generated in the context of the main thread, but subscription is shifted
323+
The integers are generated in the context of the main thread, but the subscription is shifted
324324
to another thread using Rx
325325
[observeOn](https://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Flowable.html#observeOn(io.reactivex.Scheduler,%20boolean,%20int))
326326
operator with a buffer of size 1.
@@ -370,14 +370,14 @@ Complete
370370

371371
<!--- TEST -->
372372

373-
We see here how producer coroutine puts the first element in the buffer and is suspended while trying to send another
374-
one. Only after consumer processes the first item, producer sends the second one and resumes, etc.
373+
We see here how the producer coroutine puts the first element in the buffer and is suspended while trying to send another
374+
one. Only after the consumer processes the first item, the producer sends the second one and resumes, etc.
375375

376376

377377
### Rx Subject vs BroadcastChannel
378378

379379
RxJava has a concept of [Subject](https://github.com/ReactiveX/RxJava/wiki/Subject) which is an object that
380-
effectively broadcasts elements to all its subscribers. The matching concept in coroutines world is called a
380+
effectively broadcasts elements to all its subscribers. The matching concept in the coroutines world is called a
381381
[BroadcastChannel]. There is a variety of subjects in Rx with
382382
[BehaviorSubject](https://reactivex.io/RxJava/2.x/javadoc/io/reactivex/subjects/BehaviorSubject.html) being
383383
the one used to manage state:
@@ -445,15 +445,15 @@ four
445445

446446
<!--- TEST -->
447447

448-
Here we use [Dispatchers.Unconfined] coroutine context to launch consuming coroutine with the same behaviour as subscription in Rx.
448+
Here we use the [Dispatchers.Unconfined] coroutine context to launch a consuming coroutine with the same behavior as subscription in Rx.
449449
It basically means that the launched coroutine is going to be immediately executed in the same thread that
450450
is emitting elements. Contexts are covered in more details in a [separate section](#coroutine-context).
451451

452452
The advantage of coroutines is that it is easy to get conflation behavior for single-threaded UI updates.
453453
A typical UI application does not need to react to every state change. Only the most recent state is relevant.
454454
A sequence of back-to-back updates to the application state needs to get reflected in UI only once,
455455
as soon as the UI thread is free. For the following example we are going to simulate this by launching
456-
consuming coroutine in the context of the main thread and use [yield] function to simulate a break in the
456+
a consuming coroutine in the context of the main thread and use the [yield] function to simulate a break in the
457457
sequence of updates and to release the main thread:
458458

459459
<!--- INCLUDE
@@ -475,21 +475,21 @@ fun main() = runBlocking<Unit> {
475475
subject.onNext("three")
476476
subject.onNext("four")
477477
yield() // yield the main thread to the launched coroutine <--- HERE
478-
subject.onComplete() // now complete subject's sequence to cancel consumer, too
478+
subject.onComplete() // now complete the subject's sequence to cancel the consumer, too
479479
}
480480
```
481481

482482
> You can get full code [here](kotlinx-coroutines-rx2/test/guide/example-reactive-basic-08.kt).
483483
484-
Now coroutine process (prints) only the most recent update:
484+
Now the coroutine processes (prints) only the most recent update:
485485

486486
```text
487487
four
488488
```
489489

490490
<!--- TEST -->
491491

492-
The corresponding behavior in a pure coroutines world is implemented by [ConflatedBroadcastChannel]
492+
The corresponding behavior in the pure coroutines world is implemented by [ConflatedBroadcastChannel]
493493
that provides the same logic on top of coroutine channels directly,
494494
without going through the bridge to the reactive streams:
495495

@@ -511,7 +511,7 @@ fun main() = runBlocking<Unit> {
511511
broadcast.offer("three")
512512
broadcast.offer("four")
513513
yield() // yield the main thread to the launched coroutine
514-
broadcast.close() // now close broadcast channel to cancel consumer, too
514+
broadcast.close() // now close the broadcast channel to cancel the consumer, too
515515
}
516516
```
517517

@@ -528,10 +528,10 @@ four
528528
Another implementation of [BroadcastChannel] is `ArrayBroadcastChannel` with an array-based buffer of
529529
a specified `capacity`. It can be created with `BroadcastChannel(capacity)`.
530530
It delivers every event to every
531-
subscriber since the moment the corresponding subscription is open. It corresponds to
531+
subscriber as soon as their corresponding subscriptions are opened. It corresponds to
532532
[PublishSubject](https://reactivex.io/RxJava/2.x/javadoc/io/reactivex/subjects/PublishSubject.html) in Rx.
533533
The capacity of the buffer in the constructor of `ArrayBroadcastChannel` controls the numbers of elements
534-
that can be sent before the sender is suspended waiting for receiver to receive those elements.
534+
that can be sent before the sender is suspended waiting for a receiver to receive those elements.
535535

536536
## Operators
537537

@@ -545,13 +545,13 @@ Coroutines and channels are designed to provide an opposite experience. There ar
545545
but processing streams of elements is extremely simple and back-pressure is supported automatically
546546
without you having to explicitly think about it.
547547

548-
This section shows coroutine-based implementation of several reactive stream operators.
548+
This section shows a coroutine-based implementation of several reactive stream operators.
549549

550550
### Range
551551

552552
Let's roll out own implementation of
553553
[range](https://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Flowable.html#range(int,%20int))
554-
operator for reactive streams `Publisher` interface. The asynchronous clean-slate implementation of this operator for
554+
operator for the reactive streams' `Publisher` interface. The asynchronous clean-slate implementation of this operator for
555555
reactive streams is explained in
556556
[this blog post](https://akarnokd.blogspot.ru/2017/03/java-9-flow-api-asynchronous-integer.html).
557557
It takes a lot of code.
@@ -569,11 +569,11 @@ fun CoroutineScope.range(context: CoroutineContext, start: Int, count: Int) = pu
569569
}
570570
```
571571

572-
In this code `CoroutineScope` and `context` are used instead of an `Executor` and all the backpressure aspects are taken care
572+
Here, `CoroutineScope` and `context` are used instead of an `Executor` and all the backpressure aspects are taken care
573573
of by the coroutines machinery. Note that this implementation depends only on the small reactive streams library
574-
that defines `Publisher` interface and its friends.
574+
that defines the `Publisher` interface and its friends.
575575

576-
It is straightforward to use from a coroutine:
576+
Using it from a coroutine is straightforward:
577577

578578
```kotlin
579579
fun main() = runBlocking<Unit> {
@@ -644,7 +644,7 @@ fun main() = runBlocking<Unit> {
644644

645645
> You can get full code [here](kotlinx-coroutines-rx2/test/guide/example-reactive-operators-02.kt).
646646
647-
It is not hard to see, that the result is going to be:
647+
It is not hard to see that the result is going to be:
648648

649649
```text
650650
2 is even
@@ -657,10 +657,10 @@ It is not hard to see, that the result is going to be:
657657

658658
Let's implement our own version of
659659
[takeUntil](https://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Flowable.html#takeUntil(org.reactivestreams.Publisher))
660-
operator. It is quite a [tricky one](https://akarnokd.blogspot.ru/2015/05/pitfalls-of-operator-implementations.html)
661-
to implement, because of the need to track and manage subscription to two streams.
660+
operator. It is quite [tricky](https://akarnokd.blogspot.ru/2015/05/pitfalls-of-operator-implementations.html)
661+
as subscriptions to two streams need to be tracked and managed.
662662
We need to relay all the elements from the source stream until the other stream either completes or
663-
emits anything. However, we have [select] expression to rescue us in coroutines implementation:
663+
emits anything. However, we have the [select] expression to rescue us in the coroutines implementation:
664664

665665
<!--- INCLUDE
666666
import kotlinx.coroutines.channels.*
@@ -732,7 +732,7 @@ There are always at least two ways for processing multiple streams of data with
732732
[select] was shown in the previous example. The other way is just to launch multiple coroutines. Let
733733
us implement
734734
[merge](https://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Flowable.html#merge(org.reactivestreams.Publisher))
735-
operator using the later approach:
735+
operator using the latter approach:
736736

737737
<!--- INCLUDE
738738
import kotlinx.coroutines.*
@@ -751,16 +751,16 @@ fun <T> Publisher<Publisher<T>>.merge(context: CoroutineContext) = GlobalScope.p
751751
}
752752
```
753753

754-
Notice, the use of
754+
Notice the use of
755755
[coroutineContext](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines/coroutine-context.html)
756756
in the invocation of [launch] coroutine builder. It is used to refer
757757
to the context of the enclosing `publish` coroutine. This way, all the coroutines that are
758758
being launched here are [children](../docs/coroutines-guide.md#children-of-a-coroutine) of the `publish`
759759
coroutine and will get cancelled when the `publish` coroutine is cancelled or is otherwise completed.
760-
Moreover, since parent coroutine waits until all children are complete, this implementation fully
760+
Moreover, since the parent coroutine waits until all the children are complete, this implementation fully
761761
merges all the received streams.
762762

763-
For a test, let us start with `rangeWithInterval` function from the previous example and write a
763+
For a test, let us start with the `rangeWithInterval` function from the previous example and write a
764764
producer that sends its results twice with some delay:
765765

766766
<!--- INCLUDE
@@ -810,7 +810,7 @@ And the results should be:
810810

811811
All the example operators that are shown in the previous section have an explicit
812812
[CoroutineContext](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines/-coroutine-context/)
813-
parameter. In Rx world it roughly corresponds to
813+
parameter. In the Rx world it roughly corresponds to
814814
a [Scheduler](https://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Scheduler.html).
815815

816816
### Threads with Rx
@@ -988,13 +988,13 @@ The resulting messages are going to be printed in the main thread:
988988
### Unconfined context
989989

990990
Most Rx operators do not have any specific thread (scheduler) associated with them and are working
991-
in whatever thread that they happen to be invoked in. We've seen it on the example of `subscribe` operator
991+
in whatever thread they happen to be invoked. We've seen it in the example with the `subscribe` operator
992992
in the [threads with Rx](#threads-with-rx) section.
993993

994994
In the world of coroutines, [Dispatchers.Unconfined] context serves a similar role. Let us modify our previous example,
995995
but instead of iterating over the source `Flowable` from the `runBlocking` coroutine that is confined
996-
to the main thread, we launch a new coroutine in `Dispatchers.Unconfined` context, while the main coroutine
997-
simply waits its completion using [Job.join]:
996+
to the main thread, we launch a new coroutine in the `Dispatchers.Unconfined` context, while the main coroutine
997+
simply waits for its completion using [Job.join]:
998998

999999
<!--- INCLUDE
10001000
import io.reactivex.*
@@ -1024,7 +1024,7 @@ fun main() = runBlocking<Unit> {
10241024
> You can get full code [here](kotlinx-coroutines-rx2/test/guide/example-reactive-context-05.kt).
10251025
10261026
Now, the output shows that the code of the coroutine is executing in the Rx computation thread pool, just
1027-
like our initial example using Rx `subscribe` operator.
1027+
like our initial example using the Rx `subscribe` operator.
10281028

10291029
```text
10301030
1 on thread RxComputationThreadPool-1
@@ -1034,14 +1034,14 @@ like our initial example using Rx `subscribe` operator.
10341034

10351035
<!--- TEST LINES_START -->
10361036

1037-
Note that [Dispatchers.Unconfined] context shall be used with care. It may improve the overall performance on certain tests,
1037+
Note that the [Dispatchers.Unconfined] context should be used with care. It may improve the overall performance on certain tests,
10381038
due to the increased stack-locality of operations and less scheduling overhead, but it also produces deeper stacks
10391039
and makes it harder to reason about asynchronicity of the code that is using it.
10401040

10411041
If a coroutine sends an element to a channel, then the thread that invoked the
1042-
[send][SendChannel.send] may start executing the code of a coroutine with [Dispatchers.Unconfined] dispatcher.
1042+
[send][SendChannel.send] may start executing the code of the coroutine with the [Dispatchers.Unconfined] dispatcher.
10431043
The original producer coroutine that invoked `send` is paused until the unconfined consumer coroutine hits its next
1044-
suspension point. This is very similar to a lock-step single-threaded `onNext` execution in Rx world in the absense
1044+
suspension point. This is very similar to a lock-step single-threaded `onNext` execution in the Rx world in the absense
10451045
of thread-shifting operators. It is a normal default for Rx, because operators are usually doing very small chunks
10461046
of work and you have to combine many operators for a complex processing. However, this is unusual with coroutines,
10471047
where you can have an arbitrary complex processing in a coroutine. Usually, you only need to chain stream-processing

0 commit comments

Comments
 (0)