diff --git a/docs/cfg/buildprofiles.xml b/docs/cfg/buildprofiles.xml index d4a99434cd..d1a081cad8 100644 --- a/docs/cfg/buildprofiles.xml +++ b/docs/cfg/buildprofiles.xml @@ -1,10 +1,9 @@ - - - - true - https://github.com/Kotlin/kotlinx.coroutines/edit/master/docs/ - true - - - + + + true + https://github.com/Kotlin/kotlinx.coroutines/edit/master/docs/ + true + + + \ No newline at end of file diff --git a/docs/kc.tree b/docs/kc.tree index 9fa1e11307..0ee8a4ce10 100644 --- a/docs/kc.tree +++ b/docs/kc.tree @@ -1,25 +1,19 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/docs/project.ihp b/docs/project.ihp deleted file mode 100644 index d8da718e83..0000000000 --- a/docs/project.ihp +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/topics/cancellation-and-timeouts.md b/docs/topics/cancellation-and-timeouts.md index c574e12624..ac99d5fee3 100644 --- a/docs/topics/cancellation-and-timeouts.md +++ b/docs/topics/cancellation-and-timeouts.md @@ -1,4 +1,5 @@ +https://github.com/Kotlin/kotlinx.coroutines/edit/master/docs/topics/ [//]: # (title: Cancellation and timeouts) @@ -31,10 +32,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-cancel-01.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-cancel-01.kt). > -{type="note"} +{style="note"} It produces the following output: @@ -85,10 +86,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-cancel-02.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-cancel-02.kt). > -{type="note"} +{style="note"} Run it to see that it continues to print "I'm sleeping" even after cancellation until the job completes by itself after five iterations. @@ -130,10 +131,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-cancel-03.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-cancel-03.kt). > -{type="note"} +{style="note"} While catching `Exception` is an anti-pattern, this issue may surface in more subtle ways, like when using the [`runCatching`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/run-catching.html) function, @@ -172,10 +173,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-cancel-04.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-cancel-04.kt). > -{type="note"} +{style="note"} As you can see, now this loop is cancelled. [isActive] is an extension property available inside the coroutine via the [CoroutineScope] object. @@ -188,7 +189,7 @@ main: I'm tired of waiting! main: Now I can quit. --> -## Closing resources with `finally` +## Closing resources with finally Cancellable suspending functions throw [CancellationException] on cancellation, which can be handled in the usual way. For example, the `try {...} finally {...}` expression and Kotlin's `use` function execute their @@ -217,10 +218,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-cancel-05.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-cancel-05.kt). > -{type="note"} +{style="note"} Both [join][Job.join] and [cancelAndJoin] wait for all finalization actions to complete, so the example above produces the following output: @@ -272,10 +273,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-cancel-06.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-cancel-06.kt). > -{type="note"} +{style="note"} +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-cancel-07.kt). > -{type="note"} +{style="note"} It produces the following output: @@ -353,10 +354,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-cancel-08.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-cancel-08.kt). > -{type="note"} +{style="note"} There is no longer an exception when running this code: @@ -414,10 +415,10 @@ fun main() { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-cancel-09.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-cancel-09.kt). > -{type="note"} +{style="note"} @@ -428,7 +429,7 @@ of your machine. You may need to tweak the timeout in this example to actually s > since it always happens from the same thread, the one used by `runBlocking`. > More on that will be explained in the chapter on coroutine context. > -{type="note"} +{style="note"} To work around this problem you can store a reference to the resource in a variable instead of returning it from the `withTimeout` block. @@ -467,10 +468,10 @@ fun main() { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-cancel-10.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-cancel-10.kt). > -{type="note"} +{style="note"} This example always prints zero. Resources do not leak. diff --git a/docs/topics/channels.md b/docs/topics/channels.md index 402fb5a170..090f9e6990 100644 --- a/docs/topics/channels.md +++ b/docs/topics/channels.md @@ -1,4 +1,5 @@ +https://github.com/Kotlin/kotlinx.coroutines/edit/master/docs/topics/ [//]: # (title: Channels) @@ -30,10 +31,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-channel-01.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-channel-01.kt). > -{type="note"} +{style="note"} The output of this code is: @@ -76,10 +77,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-channel-02.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-channel-02.kt). > -{type="note"} +{style="note"} +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-channel-03.kt). > -{type="note"} +{style="note"} +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-channel-04.kt). > -{type="note"} +{style="note"} +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-channel-05.kt). > -{type="note"} +{style="note"} The output of this code is: @@ -359,10 +360,10 @@ fun CoroutineScope.launchProcessor(id: Int, channel: ReceiveChannel) = laun } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-channel-06.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-channel-06.kt). > -{type="note"} +{style="note"} The output will be similar to the following one, albeit the processor ids that receive each specific integer may be different: @@ -434,10 +435,10 @@ suspend fun sendString(channel: SendChannel, s: String, time: Long) { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-channel-07.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-channel-07.kt). > -{type="note"} +{style="note"} The output is: @@ -484,10 +485,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-channel-08.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-channel-08.kt). > -{type="note"} +{style="note"} It prints "sending" _five_ times using a buffered channel with capacity of _four_: @@ -537,10 +538,10 @@ suspend fun player(name: String, table: Channel) { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-channel-09.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-channel-09.kt). > -{type="note"} +{style="note"} The "ping" coroutine is started first, so it is the first one to receive the ball. Even though "ping" coroutine immediately starts receiving the ball again after sending it back to the table, the ball gets @@ -601,10 +602,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-channel-10.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-channel-10.kt). > -{type="note"} +{style="note"} It prints following lines: diff --git a/docs/topics/composing-suspending-functions.md b/docs/topics/composing-suspending-functions.md index e1255c8d07..7e8c249f21 100644 --- a/docs/topics/composing-suspending-functions.md +++ b/docs/topics/composing-suspending-functions.md @@ -1,4 +1,5 @@ +https://github.com/Kotlin/kotlinx.coroutines/edit/master/docs/topics/ [//]: # (title: Composing suspending functions) @@ -59,10 +60,10 @@ suspend fun doSomethingUsefulTwo(): Int { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-compose-01.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-compose-01.kt). > -{type="note"} +{style="note"} It produces something like this: @@ -110,10 +111,10 @@ suspend fun doSomethingUsefulTwo(): Int { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-compose-02.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-compose-02.kt). > -{type="note"} +{style="note"} It produces something like this: @@ -163,10 +164,10 @@ suspend fun doSomethingUsefulTwo(): Int { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-compose-03.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-compose-03.kt). > -{type="note"} +{style="note"} It produces something like this: @@ -193,7 +194,7 @@ standard `lazy` function in cases when computation of the value involves suspend > in other programming languages. Using this style with Kotlin coroutines is **strongly discouraged** for the > reasons explained below. > -{type="note"} +{style="note"} We can define async-style functions that invoke `doSomethingUsefulOne` and `doSomethingUsefulTwo` _asynchronously_ using the [async] coroutine builder using a [GlobalScope] reference to @@ -205,7 +206,7 @@ to use the resulting deferred value to get the result. > [GlobalScope] is a delicate API that can backfire in non-trivial ways, one of which will be explained > below, so you must explicitly opt-in into using `GlobalScope` with `@OptIn(DelicateCoroutinesApi::class)`. > -{type="note"} +{style="note"} ```kotlin // The result type of somethingUsefulOneAsync is Deferred @@ -271,10 +272,10 @@ suspend fun doSomethingUsefulTwo(): Int { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-compose-04.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-compose-04.kt). > -{type="note"} +{style="note"} +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-compose-05.kt). > -{type="note"} +{style="note"} We still have concurrent execution of both operations, as evident from the output of the above `main` function: @@ -384,10 +385,10 @@ suspend fun failedConcurrentSum(): Int = coroutineScope { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-compose-06.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-compose-06.kt). > -{type="note"} +{style="note"} Note how both the first `async` and the awaiting parent are cancelled on failure of one of the children (namely, `two`): diff --git a/docs/topics/coroutine-context-and-dispatchers.md b/docs/topics/coroutine-context-and-dispatchers.md index ffbb364289..89498af00e 100644 --- a/docs/topics/coroutine-context-and-dispatchers.md +++ b/docs/topics/coroutine-context-and-dispatchers.md @@ -1,4 +1,5 @@ +https://github.com/Kotlin/kotlinx.coroutines/edit/master/docs/topics/ [//]: # (title: Coroutine context and dispatchers) @@ -42,10 +43,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-context-01.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-context-01.kt). > -{type="note"} +{style="note"} It produces the following output (maybe in different order): @@ -104,10 +105,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-context-02.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-context-02.kt). > -{type="note"} +{style="note"} Produces the output: @@ -129,7 +130,7 @@ function is using. > because some operation in a coroutine must be performed right away. > The unconfined dispatcher should not be used in general code. > -{type="note"} +{style="note"} ## Debugging coroutines and threads @@ -143,7 +144,7 @@ The Coroutine Debugger of the Kotlin plugin simplifies debugging coroutines in I > Debugging works for versions 1.3.8 or later of `kotlinx-coroutines-core`. > -{type="note"} +{style="note"} The **Debug** tool window contains the **Coroutines** tab. In this tab, you can find information about both currently running and suspended coroutines. The coroutines are grouped by the dispatcher they are running on. @@ -190,10 +191,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-context-03.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-context-03.kt). > -{type="note"} +{style="note"} There are three coroutines. The main coroutine (#1) inside `runBlocking` and two coroutines computing the deferred values `a` (#2) and `b` (#3). @@ -215,7 +216,7 @@ is consecutively assigned to all created coroutines when the debugging mode is o > Debugging mode is also turned on when JVM is run with `-ea` option. > You can read more about debugging facilities in the documentation of the [DEBUG_PROPERTY_NAME] property. > -{type="note"} +{style="note"} ## Jumping between threads @@ -240,10 +241,10 @@ fun main() { } } ``` - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-context-04.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-context-04.kt). > -{type="note"} +{style="note"} It demonstrates several new techniques. One is using [runBlocking] with an explicitly specified context, and the other one is using the [withContext] function to change the context of a coroutine while still staying in the @@ -275,10 +276,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-context-05.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-context-05.kt). > -{type="note"} +{style="note"} In the [debug mode](#debugging-coroutines-and-threads), it outputs something like this: @@ -337,10 +338,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-context-06.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-context-06.kt). > -{type="note"} +{style="note"} The output of this code is: @@ -379,10 +380,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-context-07.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-context-07.kt). > -{type="note"} +{style="note"} The result is going to be: @@ -430,10 +431,10 @@ fun main() = runBlocking(CoroutineName("main")) { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-context-08.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-context-08.kt). > -{type="note"} +{style="note"} The output it produces with `-Dkotlinx.coroutines.debug` JVM option is similar to: @@ -464,10 +465,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-context-09.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-context-09.kt). > -{type="note"} +{style="note"} The output of this code with the `-Dkotlinx.coroutines.debug` JVM option is: @@ -559,10 +560,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-context-10.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-context-10.kt). > -{type="note"} +{style="note"} The output of this example is: @@ -581,7 +582,7 @@ by a single invocation of `job.cancel()` in `Activity.destroy()`. > Note, that Android has first-party support for coroutine scope in all entities with the lifecycle. > See [the corresponding documentation](https://developer.android.com/topic/libraries/architecture/coroutines#lifecyclescope). > -{type="note"} +{style="note"} ### Thread-local data @@ -614,10 +615,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-context-11.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-context-11.kt). > -{type="note"} +{style="note"} In this example we launch a new coroutine in a background thread pool using [Dispatchers.Default], so it works on a different thread from the thread pool, but it still has the value of the thread local variable diff --git a/docs/topics/coroutines-and-channels.md b/docs/topics/coroutines-and-channels.md index e3cb7e5a42..45081dc8bc 100644 --- a/docs/topics/coroutines-and-channels.md +++ b/docs/topics/coroutines-and-channels.md @@ -1,3 +1,5 @@ +https://github.com/Kotlin/kotlinx.coroutines/edit/master/docs/topics/ + [//]: # (title: Coroutines and channels − tutorial) In this tutorial, you'll learn how to use coroutines in IntelliJ IDEA to perform network requests without blocking the @@ -5,7 +7,7 @@ underlying thread or callbacks. > No prior knowledge of coroutines is required, but you're expected to be familiar with basic Kotlin syntax. > -{type="tip"} +{style="tip"} You'll learn: @@ -18,7 +20,7 @@ this tutorial works similarly for any other libraries that support coroutines. > You can find solutions for all of the tasks on the `solutions` branch of the [project's repository](http://github.com/kotlin-hands-on/intro-coroutines). > -{type="tip"} +{style="tip"} ## Before you start @@ -186,13 +188,13 @@ The corresponding test file `test/tasks/AggregationKtTest.kt` shows an example o > You can jump between the source code and the test class automatically by using the [IntelliJ IDEA shortcut](https://www.jetbrains.com/help/idea/create-tests.html#test-code-navigation) > `Ctrl+Shift+T` / `⇧ ⌘ T`. > -{type="tip"} +{style="tip"} After implementing this task, the resulting list for the "kotlin" organization should be similar to the following: ![The list for the "kotlin" organization](aggregate.png){width=500} -#### Solution for task 1 {initial-collapse-state="collapsed"} +#### Solution for task 1 {initial-collapse-state="collapsed" collapsible="true"} 1. To group users by login, use [`groupBy()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/group-by.html), which returns a map from a login to all occurrences of the user with this login in different repositories. @@ -269,7 +271,7 @@ nothing changes. Fix the `loadContributorsBackground()` function in `src/tasks/Request2Background.kt` so that the resulting list is shown in the UI. -#### Solution for task 2 {initial-collapse-state="collapsed"} +#### Solution for task 2 {initial-collapse-state="collapsed" collapsible="true"} If you try to load the contributors, you can see in the log that the contributors are loaded but the result isn't displayed. To fix this, call `updateResults()` on the resulting list of users: @@ -340,7 +342,7 @@ Think about why the given code doesn't work as expected and try to fix it, or se Rewrite the code in the `src/tasks/Request3Callbacks.kt` file so that the loaded list of contributors is shown. -#### The first attempted solution for task 3 {initial-collapse-state="collapsed"} +#### The first attempted solution for task 3 {initial-collapse-state="collapsed" collapsible="true"} In the current solution, many requests are started concurrently, which decreases the total loading time. However, the result isn't loaded. This is because the `updateResults()` callback is called right after all of the loading requests are started, @@ -369,7 +371,7 @@ for ((index, repo) in repos.withIndex()) { // #1 However, this code also fails to achieve our objective. Try to find the answer yourself, or see the solution below. -#### The second attempted solution for task 3 {initial-collapse-state="collapsed"} +#### The second attempted solution for task 3 {initial-collapse-state="collapsed" collapsible="true"} Since the loading requests are started concurrently, there's no guarantee that the result for the last one comes last. The results can come in any order. @@ -401,7 +403,7 @@ for (repo in repos) { This code uses a synchronized version of the list and `AtomicInteger()` because, in general, there's no guarantee that different callbacks that process `getRepoContributors()` requests will always be called from the same thread. -#### The third attempted solution for task 3 {initial-collapse-state="collapsed"} +#### The third attempted solution for task 3 {initial-collapse-state="collapsed" collapsible="true"} An even better solution is to use the `CountDownLatch` class. It stores a counter initialized with the number of repositories. This counter is decremented after processing each repository. It then waits until the latch is counted @@ -429,7 +431,7 @@ and error-prone, especially when several underlying threads and synchronization > necessary dependencies and solutions for using RxJava can be found in a separate `rx` branch. It is also possible to > complete this tutorial and implement or check the proposed Rx versions for a proper comparison. > -{type="tip"} +{style="tip"} ## Suspending functions @@ -482,7 +484,7 @@ new API. > result in an error with the message "Suspend function 'getOrgRepos' should be called only from a coroutine or another > suspend function". > -{type="note"} +{style="note"} 1. Copy the implementation of `loadContributorsBlocking()` that is defined in `src/tasks/Request1Blocking.kt` into the `loadContributorsSuspend()` that is defined in `src/tasks/Request4Suspend.kt`. @@ -490,7 +492,7 @@ new API. 3. Run the program by choosing the _SUSPEND_ option and ensure that the UI is still responsive while the GitHub requests are performed. -#### Solution for task 4 {initial-collapse-state="collapsed"} +#### Solution for task 4 {initial-collapse-state="collapsed" collapsible="true"} Replace `.getOrgReposCall(req.org).execute()` with `.getOrgRepos(req.org)` and repeat the same replacement for the second "contributors" request: @@ -528,7 +530,7 @@ thread -> coroutine > Coroutines are often called lightweight threads because you can run code on coroutines, similar to how you run code on > threads. The operations that were blocking before (and had to be avoided) can now suspend the coroutine instead. > -{type="note"} +{style="note"} ### Starting a new coroutine @@ -640,7 +642,7 @@ tests. > Watch [this video](https://www.youtube.com/watch?v=zEZc5AmHQhk) for a better understanding of coroutines. > -{type="tip"} +{style="tip"} If there is a list of deferred objects, you can call `awaitAll()` to await the results of all of them: @@ -673,7 +675,7 @@ What's more, `async` explicitly emphasizes which parts run concurrently in the c In the `Request5Concurrent.kt` file, implement a `loadContributorsConcurrent()` function by using the previous `loadContributorsSuspend()` function. -#### Tip for task 5 {initial-collapse-state="collapsed"} +#### Tip for task 5 {initial-collapse-state="collapsed" collapsible="true"} You can only start a new coroutine inside a coroutine scope. Copy the content from `loadContributorsSuspend()` to the `coroutineScope` call so that you can call `async` functions there: @@ -698,7 +700,7 @@ val deferreds: List>> = repos.map { repo -> deferreds.awaitAll() // List> ``` -#### Solution for task 5 {initial-collapse-state="collapsed"} +#### Solution for task 5 {initial-collapse-state="collapsed" collapsible="true"} Wrap each "contributors" request with `async` to create as many coroutines as there are repositories. `async` returns `Deferred>`. This is not an issue because creating new coroutines is not very resource-intensive, so you can @@ -1042,7 +1044,7 @@ top-level coroutine. All the nested coroutines then inherit the context and modi > use `CoroutineDispatchers.Main` by default for the top coroutine and then to explicitly put a different dispatcher when > you need to run the code on a different thread. > -{type="tip"} +{style="tip"} ## Showing progress @@ -1098,7 +1100,7 @@ progress. Base it on the `loadContributorsSuspend()` function from `Request4Susp * The total number of contributions for each user should be increased when the data for each new repository is loaded. -#### Solution for task 6 {initial-collapse-state="collapsed"} +#### Solution for task 6 {initial-collapse-state="collapsed" collapsible="true"} To store the intermediate list of loaded contributors in the "aggregated" state, define an `allUsers` variable which stores the list of users, and then update it after contributors for each new repository are loaded: @@ -1267,7 +1269,7 @@ fun log(message: Any?) { > Watch [this video](https://www.youtube.com/watch?v=HpWQUoVURWQ) for a better understanding of channels. > -{type="tip"} +{style="tip"} ### Task 7 @@ -1277,7 +1279,7 @@ contributors concurrently and shows intermediate progress at the same time. Use the previous functions, `loadContributorsConcurrent()` from `Request5Concurrent.kt` and `loadContributorsProgress()` from `Request6Progress.kt`. -#### Tip for task 7 {initial-collapse-state="collapsed"} +#### Tip for task 7 {initial-collapse-state="collapsed" collapsible="true"} Different coroutines that concurrently receive contributor lists for different repositories can send all of the received results to the same channel: @@ -1304,7 +1306,7 @@ repeat(repos.size) { Since the `receive()` calls are sequential, no additional synchronization is needed. -#### Solution for task 7 {initial-collapse-state="collapsed"} +#### Solution for task 7 {initial-collapse-state="collapsed" collapsible="true"} As with the `loadContributorsProgress()` function, you can create an `allUsers` variable to store the intermediate states of the "all contributors" list. @@ -1459,7 +1461,7 @@ which allows for more flexibility and easier testing. > The testing API that supports virtual time is [Experimental](components-stability.md) and may change in the future. > -{type="warning"} +{style="warning"} By default, the compiler shows warnings if you use the experimental testing API. To suppress these warnings, annotate the test function or the whole class containing the tests with `@OptIn(ExperimentalCoroutinesApi::class)`. @@ -1486,7 +1488,7 @@ Refactor the following tests in `tests/tasks/` to use virtual time instead of re Compare the total running times before and after applying your refactoring. -#### Tip for task 8 {initial-collapse-state="collapsed"} +#### Tip for task 8 {initial-collapse-state="collapsed" collapsible="true"} 1. Replace the `runBlocking` invocation with `runTest`, and replace `System.currentTimeMillis()` with `currentTime`: @@ -1503,7 +1505,7 @@ Compare the total running times before and after applying your refactoring. 2. Uncomment the assertions that check the exact virtual time. 3. Don't forget to add `@UseExperimental(ExperimentalCoroutinesApi::class)`. -#### Solution for task 8 {initial-collapse-state="collapsed"} +#### Solution for task 8 {initial-collapse-state="collapsed" collapsible="true"} Here are the solutions for the concurrent and channels cases: @@ -1547,7 +1549,7 @@ can see the difference in tests that use virtual time. > The tests for the remaining "suspend" and "progress" tasks are very similar – you can find them in the project's > `solutions` branch. > -{type="tip"} +{style="tip"} ## What's next diff --git a/docs/topics/coroutines-basics.md b/docs/topics/coroutines-basics.md index 8a5b4304ad..68a1a01957 100644 --- a/docs/topics/coroutines-basics.md +++ b/docs/topics/coroutines-basics.md @@ -1,4 +1,5 @@ +https://github.com/Kotlin/kotlinx.coroutines/edit/master/docs/topics/ [//]: # (title: Coroutines basics) @@ -29,10 +30,10 @@ fun main() = runBlocking { // this: CoroutineScope //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-basic-01.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-basic-01.kt). > -{type="note"} +{style="note"} You will see the following result: @@ -59,7 +60,7 @@ the code with coroutines inside of `runBlocking { ... }` curly braces. This is h If you remove or forget `runBlocking` in this code, you'll get an error on the [launch] call, since `launch` is declared only on the [CoroutineScope]: -```Plain Text +``` Unresolved reference: launch ``` @@ -104,10 +105,10 @@ suspend fun doWorld() { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-basic-02.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-basic-02.kt). > -{type="note"} +{style="note"} +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-basic-03.kt). > -{type="note"} +{style="note"} This code also prints: @@ -189,10 +190,10 @@ suspend fun doWorld() = coroutineScope { // this: CoroutineScope //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-basic-04.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-basic-04.kt). > -{type="note"} +{style="note"} Both pieces of code inside `launch { ... }` blocks execute _concurrently_, with `World 1` printed first, after a second from start, and `World 2` printed next, after two seconds from start. @@ -230,10 +231,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-basic-05.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-basic-05.kt). > -{type="note"} +{style="note"} This code produces: @@ -266,10 +267,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-basic-06.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-basic-06.kt). > -{type="note"} +{style="note"} diff --git a/docs/topics/coroutines-guide.md b/docs/topics/coroutines-guide.md index fd95c38dee..a77acf43f8 100644 --- a/docs/topics/coroutines-guide.md +++ b/docs/topics/coroutines-guide.md @@ -1,3 +1,6 @@ +https://github.com/Kotlin/kotlinx.coroutines/edit/master/docs/topics/ + + [//]: # (title: Coroutines guide) Kotlin provides only minimal low-level APIs in its standard library to enable other diff --git a/docs/topics/debug-coroutines-with-idea.md b/docs/topics/debug-coroutines-with-idea.md index b31aa79f51..9ac49fddbb 100644 --- a/docs/topics/debug-coroutines-with-idea.md +++ b/docs/topics/debug-coroutines-with-idea.md @@ -1,3 +1,6 @@ +https://github.com/Kotlin/kotlinx.coroutines/edit/master/docs/topics/ + + [//]: # (title: Debug coroutines using IntelliJ IDEA – tutorial) This tutorial demonstrates how to create Kotlin coroutines and debug them using IntelliJ IDEA. @@ -113,4 +116,4 @@ You can disable this behavior with the `-Xdebug` compiler option. > __Never use this flag in production__: `-Xdebug` can [cause memory leaks](https://youtrack.jetbrains.com/issue/KT-48678/Coroutine-debugger-disable-was-optimised-out-compiler-feature#focus=Comments-27-6015585.0-0). > -{type="warning"} \ No newline at end of file +{style="warning"} \ No newline at end of file diff --git a/docs/topics/debug-flow-with-idea.md b/docs/topics/debug-flow-with-idea.md index 0aa78b1780..4e2541bc89 100644 --- a/docs/topics/debug-flow-with-idea.md +++ b/docs/topics/debug-flow-with-idea.md @@ -1,3 +1,6 @@ +https://github.com/Kotlin/kotlinx.coroutines/edit/master/docs/topics/ + + [//]: # (title: Debug Kotlin Flow using IntelliJ IDEA – tutorial) This tutorial demonstrates how to create Kotlin Flow and debug it using IntelliJ IDEA. @@ -114,7 +117,7 @@ You can disable this behavior with the `-Xdebug` compiler option. > __Never use this flag in production__: `-Xdebug` can [cause memory leaks](https://youtrack.jetbrains.com/issue/KT-48678/Coroutine-debugger-disable-was-optimised-out-compiler-feature#focus=Comments-27-6015585.0-0). > -{type="warning"} +{style="warning"} ## Add a concurrently running coroutine diff --git a/docs/topics/exception-handling.md b/docs/topics/exception-handling.md index f79740c95f..936688ebf3 100644 --- a/docs/topics/exception-handling.md +++ b/docs/topics/exception-handling.md @@ -1,4 +1,5 @@ +https://github.com/Kotlin/kotlinx.coroutines/edit/master/docs/topics/ [//]: # (title: Coroutine exceptions handling) @@ -23,7 +24,7 @@ It can be demonstrated by a simple example that creates root coroutines using th > whole application is one of the rare legitimate uses for `GlobalScope`, so you must explicitly opt-in into > using `GlobalScope` with `@OptIn(DelicateCoroutinesApi::class)`. > -{type="note"} +{style="note"} ```kotlin import kotlinx.coroutines.* @@ -51,10 +52,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-exceptions-01.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-exceptions-01.kt). > -{type="note"} +{style="note"} The output of this code is (with [debug](https://github.com/Kotlin/kotlinx.coroutines/blob/master/docs/coroutine-context-and-dispatchers.md#debugging-coroutines-and-threads)): @@ -89,7 +90,7 @@ so its `CoroutineExceptionHandler` has no effect either. > Coroutines running in supervision scope do not propagate exceptions to their parent and are > excluded from this rule. A further [Supervision](#supervision) section of this document gives more details. > -{type="note"} +{style="note"} ```kotlin import kotlinx.coroutines.* @@ -111,10 +112,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-exceptions-02.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-exceptions-02.kt). > -{type="note"} +{style="note"} The output of this code is: @@ -156,10 +157,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-exceptions-03.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-exceptions-03.kt). > -{type="note"} +{style="note"} The output of this code is: @@ -181,7 +182,7 @@ This behaviour cannot be overridden and is used to provide stable coroutines hie > is launched in the scope of the main [runBlocking], since the main coroutine is going to be always cancelled > when its child completes with exception despite the installed handler. > -{type="note"} +{style="note"} The original exception is handled by the parent only when all its children terminate, which is demonstrated by the following example. @@ -218,10 +219,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-exceptions-04.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-exceptions-04.kt). > -{type="note"} +{style="note"} The output of this code is: @@ -271,10 +272,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-exceptions-05.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-exceptions-05.kt). > -{type="note"} +{style="note"} The output of this code is: @@ -287,7 +288,7 @@ CoroutineExceptionHandler got java.io.IOException with suppressed [java.lang.Ari > Note that this mechanism currently only works on Java version 1.7+. > The JS and Native restrictions are temporary and will be lifted in the future. > -{type="note"} +{style="note"} Cancellation exceptions are transparent and are unwrapped by default: @@ -321,10 +322,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-exceptions-06.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-exceptions-06.kt). > -{type="note"} +{style="note"} The output of this code is: @@ -387,10 +388,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-supervision-01.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-supervision-01.kt). > -{type="note"} +{style="note"} The output of this code is: @@ -437,10 +438,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-supervision-02.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-supervision-02.kt). > -{type="note"} +{style="note"} The output of this code is: @@ -483,10 +484,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-supervision-03.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-supervision-03.kt). > -{type="note"} +{style="note"} The output of this code is: diff --git a/docs/topics/flow.md b/docs/topics/flow.md index c436c2cfc9..3f8c694943 100644 --- a/docs/topics/flow.md +++ b/docs/topics/flow.md @@ -1,4 +1,5 @@ +https://github.com/Kotlin/kotlinx.coroutines/edit/master/docs/topics/ [//]: # (title: Asynchronous Flow) @@ -19,10 +20,10 @@ fun main() { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-01.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-01.kt). > -{type="note"} +{style="note"} This code outputs: @@ -52,10 +53,10 @@ fun main() { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-02.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-02.kt). > -{type="note"} +{style="note"} This code outputs the same numbers, but it waits 100ms before printing each one. @@ -86,10 +87,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-03.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-03.kt). > -{type="note"} +{style="note"} This code prints the numbers after waiting for a second. @@ -130,10 +131,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-04.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-04.kt). > -{type="note"} +{style="note"} This code waits 100ms before printing each number without blocking the main thread. This is verified by printing "I'm not blocked" every 100ms from a separate coroutine that is running in the main thread: @@ -160,7 +161,7 @@ Notice the following differences in the code with the [Flow] from the earlier ex > We can replace [delay] with `Thread.sleep` in the body of `simple`'s `flow { ... }` and see that the main > thread is blocked in this case. > -{type="note"} +{style="note"} ## Flows are cold @@ -191,10 +192,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-05.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-05.kt). > -{type="note"} +{style="note"} Which prints: @@ -247,10 +248,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-06.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-06.kt). > -{type="note"} +{style="note"} Notice how only two numbers get emitted by the flow in the `simple` function, producing the following output: @@ -288,10 +289,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-07.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-07.kt). > -{type="note"} +{style="note"} +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-08.kt). > -{type="note"} +{style="note"} It produces the following three lines, each appearing one second after the previous: @@ -378,10 +379,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-09.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-09.kt). > -{type="note"} +{style="note"} The output of this code is: @@ -426,10 +427,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-10.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-10.kt). > -{type="note"} +{style="note"} The output of this code clearly shows that the execution of the `flow { ... }` body in the `numbers()` function stopped after emitting the second number: @@ -467,10 +468,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-11.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-11.kt). > -{type="note"} +{style="note"} Prints a single number: @@ -511,10 +512,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-12.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-12.kt). > -{type="note"} +{style="note"} Producing: @@ -574,10 +575,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-13.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-13.kt). > -{type="note"} +{style="note"} Running this code produces: @@ -624,10 +625,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-14.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-14.kt). > -{type="note"} +{style="note"} This code produces the following exception: @@ -670,10 +671,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-15.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-15.kt). > -{type="note"} +{style="note"} Notice how `flow { ... }` works in the background thread, while collection happens in the main thread: @@ -725,10 +726,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-16.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-16.kt). > -{type="note"} +{style="note"} It produces something like this, with the whole collection taking around 1200 ms (three numbers, 400 ms for each): @@ -771,10 +772,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-17.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-17.kt). > -{type="note"} +{style="note"} It produces the same numbers just faster, as we have effectively created a processing pipeline, having to only wait 100 ms for the first number and then spending only 300 ms to process @@ -792,7 +793,7 @@ Collected in 1071 ms > Note that the [flowOn] operator uses the same buffering mechanism when it has to change a [CoroutineDispatcher], > but here we explicitly request buffering without changing the execution context. > -{type="note"} +{style="note"} ### Conflation @@ -827,10 +828,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-18.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-18.kt). > -{type="note"} +{style="note"} We see that while the first number was still being processed the second, and third were already produced, so the second one was _conflated_ and only the most recent (the third one) was delivered to the collector: @@ -877,10 +878,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-19.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-19.kt). > -{type="note"} +{style="note"} Since the body of [collectLatest] takes 300 ms, but new values are emitted every 100 ms, we see that the block is run on every value, but completes only for the last value: @@ -918,10 +919,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-20.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-20.kt). > -{type="note"} +{style="note"} This example prints: @@ -947,7 +948,7 @@ albeit results that are printed every 400 ms: > We use a [onEach] intermediate operator in this example to delay each element and make the code > that emits sample flows more declarative and shorter. > -{type="note"} +{style="note"} ```kotlin import kotlinx.coroutines.* @@ -966,10 +967,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-21.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-21.kt). > -{type="note"} +{style="note"} +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-22.kt). > -{type="note"} +{style="note"} We get quite a different output, where a line is printed at each emission from either `nums` or `strs` flows: @@ -1070,10 +1071,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-23.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-23.kt). > -{type="note"} +{style="note"} The sequential nature of [flatMapConcat] is clearly seen in the output: @@ -1118,10 +1119,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-24.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-24.kt). > -{type="note"} +{style="note"} The concurrent nature of [flatMapMerge] is obvious: @@ -1140,7 +1141,7 @@ The concurrent nature of [flatMapMerge] is obvious: > collects the resulting flows concurrently, it is the equivalent of performing a sequential > `map { requestFlow(it) }` first and then calling [flattenMerge] on the result. > -{type="note"} +{style="note"} ### flatMapLatest @@ -1171,10 +1172,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-25.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-25.kt). > -{type="note"} +{style="note"} The output here in this example is a good demonstration of how [flatMapLatest] works: @@ -1193,7 +1194,7 @@ The output here in this example is a good demonstration of how [flatMapLatest] w > and cannot be cancelled. However, a differnce in output would be visible if we were to use suspending functions > like `delay` in `requestFlow`. > -{type="note"} +{style="note"} ## Flow exceptions @@ -1229,10 +1230,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-26.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-26.kt). > -{type="note"} +{style="note"} This code successfully catches an exception in [collect] terminal operator and, as we see, no more values are emitted after that: @@ -1280,10 +1281,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-27.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-27.kt). > -{type="note"} +{style="note"} This exception is still caught and collection is stopped: @@ -1339,10 +1340,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-28.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-28.kt). > -{type="note"} +{style="note"} The output of the example is the same, even though we do not have `try/catch` around the code anymore. @@ -1382,10 +1383,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-29.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-29.kt). > -{type="note"} +{style="note"} A "Caught ..." message is not printed despite there being a `catch` operator: @@ -1429,10 +1430,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-30.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-30.kt). > -{type="note"} +{style="note"} Now we can see that a "Caught ..." message is printed and so we can catch all the exceptions without explicitly using a `try/catch` block: @@ -1473,10 +1474,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-31.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-31.kt). > -{type="note"} +{style="note"} This code prints three numbers produced by the `simple` flow followed by a "Done" string: @@ -1511,10 +1512,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-32.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-32.kt). > -{type="note"} +{style="note"} +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-33.kt). > -{type="note"} +{style="note"} As you may expect, it prints: @@ -1588,10 +1589,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-34.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-34.kt). > -{type="note"} +{style="note"} We can see the completion cause is not null, because the flow was aborted due to downstream exception: @@ -1637,10 +1638,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-35.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-35.kt). > -{type="note"} +{style="note"} As you can see, it prints: @@ -1674,10 +1675,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-36.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-36.kt). > -{type="note"} +{style="note"} It prints: @@ -1730,10 +1731,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-37.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-37.kt). > -{type="note"} +{style="note"} We get only numbers up to 3 and a [CancellationException] after trying to emit number 4: @@ -1768,10 +1769,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-38.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-38.kt). > -{type="note"} +{style="note"} All numbers from 1 to 5 are collected and cancellation gets detected only before return from `runBlocking`: @@ -1806,10 +1807,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code from [here](../../kotlinx-coroutines-core/jvm/test/guide/example-flow-39.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-39.kt). > -{type="note"} +{style="note"} With the `cancellable` operator only the numbers from 1 to 3 are collected: diff --git a/docs/topics/select-expression.md b/docs/topics/select-expression.md index 0e95ab63ea..ded445b260 100644 --- a/docs/topics/select-expression.md +++ b/docs/topics/select-expression.md @@ -1,4 +1,5 @@ +https://github.com/Kotlin/kotlinx.coroutines/edit/master/docs/topics/ [//]: # (title: Select expression \(experimental\)) @@ -9,7 +10,7 @@ the first one that becomes available. > evolve in the upcoming updates of the `kotlinx.coroutines` library with potentially > breaking changes. > -{type="note"} +{style="note"} ## Selecting from channels @@ -98,10 +99,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-select-01.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-select-01.kt). > -{type="note"} +{style="note"} The result of this code is: @@ -193,10 +194,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-select-02.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-select-02.kt). > -{type="note"} +{style="note"} The result of this code is quite interesting, so we'll analyze it in more detail: @@ -278,10 +279,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-select-03.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-select-03.kt). > -{type="note"} +{style="note"} So let us see what happens: @@ -362,10 +363,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-select-04.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-select-04.kt). > -{type="note"} +{style="note"} The output is: @@ -471,10 +472,10 @@ fun main() = runBlocking { } ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-select-05.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-select-05.kt). > -{type="note"} +{style="note"} The result of this code: diff --git a/docs/topics/shared-mutable-state-and-concurrency.md b/docs/topics/shared-mutable-state-and-concurrency.md index fad13d64bc..133c9e2cfe 100644 --- a/docs/topics/shared-mutable-state-and-concurrency.md +++ b/docs/topics/shared-mutable-state-and-concurrency.md @@ -1,4 +1,5 @@ +https://github.com/Kotlin/kotlinx.coroutines/edit/master/docs/topics/ [//]: # (title: Shared mutable state and concurrency) @@ -67,10 +68,10 @@ fun main() = runBlocking { //sampleEnd ``` {kotlin-runnable="true" kotlin-min-compiler-version="1.3"} - -> You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-sync-01.kt). + +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-sync-01.kt). > -{type="note"} +{style="note"} +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-sync-02.kt). > -{type="note"} +{style="note"} +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-sync-03.kt). > -{type="note"} +{style="note"} +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-sync-04.kt). > -{type="note"} +{style="note"} +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-sync-05.kt). > -{type="note"} +{style="note"} +> You can get the full code [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-sync-06.kt). > -{type="note"} +{style="note"}