@@ -1379,7 +1379,7 @@ suspend fun massiveRun(action: suspend () -> Unit) {
1379
1379
1380
1380
<!-- - INCLUDE .*/example-sync-([0-9]+).kt -->
1381
1381
1382
- We start with a very simple action, that increments a shared mutable variable.
1382
+ We start with a very simple action that increments a shared mutable variable.
1383
1383
1384
1384
``` kotlin
1385
1385
var counter = 0
@@ -1482,7 +1482,7 @@ class GetCounter(val response: SendChannel<Int>) : CounterMsg() // a request wit
1482
1482
// This function launches a new counter actor
1483
1483
fun counterActor (request : ReceiveChannel <CounterMsg >) = launch(CommonPool ) {
1484
1484
var counter = 0 // actor state
1485
- while (true ) { // main loop of the actor
1485
+ while (isActive ) { // main loop of the actor
1486
1486
val msg = request.receive()
1487
1487
when (msg) {
1488
1488
is IncCounter -> counter++
@@ -1511,7 +1511,7 @@ works as a solution to the problem of shared mutable state.
1511
1511
1512
1512
## Select expression
1513
1513
1514
- Select expression makes it possible to await multiple suspending function simultaneously and _ select_
1514
+ Select expression makes it possible to await multiple suspending functions simultaneously and _ select_
1515
1515
the first one that becomes available.
1516
1516
1517
1517
<!-- - INCLUDE .*/example-select-([0-9]+).kt
@@ -1560,7 +1560,7 @@ suspend fun selectFizzBuzz() {
1560
1560
}
1561
1561
```
1562
1562
1563
- Let us run it for 7 times:
1563
+ Let us run it seven times:
1564
1564
1565
1565
``` kotlin
1566
1566
fun main (args : Array <String >) = runBlocking<Unit > {
@@ -1588,7 +1588,7 @@ buzz -> 'Buzz!'
1588
1588
1589
1589
The [ onReceive] [ SelectBuilder.onReceive ] clause in ` select ` fails when the channel is closed and the corresponding
1590
1590
` select ` throws an exception. We can use [ onReceiveOrNull] [ SelectBuilder.onReceiveOrNull ] clause to perform a
1591
- specific action when channel is closed. This example also show that ` select ` is an expression that returns
1591
+ specific action when the channel is closed. The following example also shows that ` select ` is an expression that returns
1592
1592
the result of its selected clause:
1593
1593
1594
1594
``` kotlin
@@ -1609,20 +1609,17 @@ suspend fun selectAorB(a: ReceiveChannel<String>, b: ReceiveChannel<String>): St
1609
1609
}
1610
1610
```
1611
1611
1612
- Lets have channel ` a ` that produces "Hello" string 4 and ` b ` that produces "World" 4 times for this example:
1612
+ Let's use it with channel ` a ` that produces "Hello" string four times and
1613
+ channel ` b ` that produces "World" four times:
1613
1614
1614
1615
``` kotlin
1615
1616
fun main (args : Array <String >) = runBlocking<Unit > {
1616
1617
// we are using the context of the main thread in this example for predictability ...
1617
1618
val a = produce<String >(context) {
1618
- repeat(4 ) {
1619
- send(" Hello $it " )
1620
- }
1619
+ repeat(4 ) { send(" Hello $it " ) }
1621
1620
}
1622
1621
val b = produce<String >(context) {
1623
- repeat(4 ) {
1624
- send(" World $it " )
1625
- }
1622
+ repeat(4 ) { send(" World $it " ) }
1626
1623
}
1627
1624
repeat(8 ) { // print first eight results
1628
1625
println (selectAorB(a, b))
@@ -1632,7 +1629,7 @@ fun main(args: Array<String>) = runBlocking<Unit> {
1632
1629
1633
1630
> You can get full code [ here] ( kotlinx-coroutines-core/src/test/kotlin/guide/example-select-02.kt )
1634
1631
1635
- The result of this code is quite interesting, so we'll analyze it in mode details :
1632
+ The result of this code is quite interesting, so we'll analyze it in mode detail :
1636
1633
1637
1634
```
1638
1635
a -> 'Hello 0'
@@ -1645,11 +1642,11 @@ Channel 'a' is closed
1645
1642
Channel 'a' is closed
1646
1643
```
1647
1644
1648
- There are a couple of observations to make out of it.
1645
+ There are couple of observations to make out of it.
1649
1646
1650
1647
First of all, ` select ` is _ biased_ to the first clause. When several clauses are selectable at the same time,
1651
1648
the first one among them gets selected. Here, both channels are constantly producing strings, so ` a ` channel,
1652
- being the first clause in select wins. However, because we are using unbuffered channel, the ` a ` gets suspended from
1649
+ being the first clause in select, wins. However, because we are using unbuffered channel, the ` a ` gets suspended from
1653
1650
time to time on its [ send] [ SendChannel.send ] invocation and gives a chance for ` b ` to send, too.
1654
1651
1655
1652
The second observation, is that [ onReceiveOrNull] [ SelectBuilder.onReceiveOrNull ] gets immediately selected when the
@@ -1660,16 +1657,16 @@ channel is already closed.
1660
1657
Select expression has [ onSend] [ SelectBuilder.onSend ] clause that can be used for a great good in combination
1661
1658
with a biased nature of selection.
1662
1659
1663
- Let us write an example of producer of integer numbers that sends its values to a ` side ` channel when
1660
+ Let us write an example of producer of integers that sends its values to a ` side ` channel when
1664
1661
the consumers on its primary channel cannot keep up with it:
1665
1662
1666
1663
``` kotlin
1667
1664
fun produceNumbers (side : SendChannel <Int >) = produce<Int >(CommonPool ) {
1668
1665
for (num in 1 .. 10 ) { // produce 10 numbers from 1 to 10
1669
1666
delay(100 ) // every 100 ms
1670
1667
select<Unit > {
1671
- onSend(num) { } // Send to the primary channel
1672
- side.onSend(num) { } // or to the side channel
1668
+ onSend(num) {} // Send to the primary channel
1669
+ side.onSend(num) {} // or to the side channel
1673
1670
}
1674
1671
}
1675
1672
}
@@ -1711,8 +1708,8 @@ Done consuming
1711
1708
1712
1709
### Selecting deferred values
1713
1710
1714
- Deferred values can be selected using [ onAwait] [ SelectBuilder.onAwait ] clause, which enables "wait first"
1715
- type of logic. Let us start with an async-style function that returns a deferred string value after
1711
+ Deferred values can be selected using [ onAwait] [ SelectBuilder.onAwait ] clause.
1712
+ Let us start with an async function that returns a deferred string value after
1716
1713
a random delay:
1717
1714
1718
1715
<!-- - INCLUDE .*/example-select-04.kt
@@ -1726,20 +1723,19 @@ fun asyncString(time: Int) = async(CommonPool) {
1726
1723
}
1727
1724
```
1728
1725
1729
- Let us start a dozen for them with random delay with the following function that returns a
1730
- collection of deferred values:
1726
+ Let us start a dozen of them with a random delay.
1731
1727
1732
1728
``` kotlin
1733
1729
fun asyncStringsList (): List <Deferred <String >> {
1734
1730
val random = Random (3 )
1735
- return ( 1 .. 12 ).map { asyncString(random.nextInt(1000 )) }
1731
+ return List ( 12 ) { asyncString(random.nextInt(1000 )) }
1736
1732
}
1737
1733
```
1738
1734
1739
- Now the main function awaits for the first of them to complete and count the number of deferred values
1735
+ Now the main function awaits for the first of them to complete and counts the number of deferred values
1740
1736
that are still active. Note, that we've used here the fact that ` select ` expression is a Kotlin DSL,
1741
- and we can provide clauses for it using an arbitrary code. In this case we iterate over a list
1742
- of deferred values to produce an ` onAwait ` clause for each one of them .
1737
+ so we can provide clauses for it using an arbitrary code. In this case we iterate over a list
1738
+ of deferred values to provide ` onAwait ` clause for each deferred value .
1743
1739
1744
1740
``` kotlin
1745
1741
fun main (args : Array <String >) = runBlocking<Unit > {
@@ -1762,19 +1758,19 @@ fun main(args: Array<String>) = runBlocking<Unit> {
1762
1758
The output is:
1763
1759
1764
1760
```
1765
- Deferred 4 produced answer 'Waited for 254 ms'
1761
+ Deferred 4 produced answer 'Waited for 128 ms'
1766
1762
11 coroutines are still active
1767
1763
```
1768
1764
1769
1765
### Switch over a channel of deferred values
1770
1766
1771
- Let us write a channel producer function that consumes a channel of deferred string values, await for each received
1772
- deferred value, but only until next deferred value comes over or the channel is closed. This example puts together
1767
+ Let us write a channel producer function that consumes a channel of deferred string values, waits for each received
1768
+ deferred value, but only until the next deferred value comes over or the channel is closed. This example puts together
1773
1769
[ onReceiveOrNull] [ SelectBuilder.onReceiveOrNull ] and [ onAwait] [ SelectBuilder.onAwait ] clauses in the same ` select ` :
1774
1770
1775
1771
``` kotlin
1776
1772
fun switchMapDeferreds (input : ReceiveChannel <Deferred <String >>) = produce<String >(CommonPool ) {
1777
- var current = input.receive() // will start with first received deferred value
1773
+ var current = input.receive() // start with first received deferred value
1778
1774
while (isActive) { // loop while not cancelled/closed
1779
1775
val next = select<Deferred <String >? > { // return next deferred value from this select or null
1780
1776
input.onReceiveOrNull { update ->
@@ -1810,19 +1806,19 @@ data to it:
1810
1806
``` kotlin
1811
1807
fun main (args : Array <String >) = runBlocking<Unit > {
1812
1808
val chan = Channel <Deferred <String >>() // the channel for test
1813
- launch(context) { // launch printing coroutines
1809
+ launch(context) { // launch printing coroutine
1814
1810
for (s in switchMapDeferreds(chan))
1815
1811
println (s) // print each received string
1816
1812
}
1817
1813
chan.send(asyncString(" BEGIN" , 100 ))
1818
1814
delay(200 ) // enough time for "BEGIN" to be produced
1819
1815
chan.send(asyncString(" Slow" , 500 ))
1820
- delay(100 ) // not enough time for slow
1816
+ delay(100 ) // not enough time to produce slow
1821
1817
chan.send(asyncString(" Replace" , 100 ))
1822
- delay(500 ) // will give it time before the last one
1818
+ delay(500 ) // give it time before the last one
1823
1819
chan.send(asyncString(" END" , 500 ))
1824
1820
delay(1000 ) // give it time to process
1825
- chan.close() // and close the channel immediately
1821
+ chan.close() // close the channel ...
1826
1822
delay(500 ) // and wait some time to let it finish
1827
1823
}
1828
1824
```
0 commit comments