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..f19da89ffa 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) @@ -32,9 +33,9 @@ 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: @@ -86,9 +87,9 @@ 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. @@ -131,9 +132,9 @@ 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, @@ -173,9 +174,9 @@ 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 @@ -218,9 +219,9 @@ 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: @@ -273,9 +274,9 @@ 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"} @@ -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. @@ -468,9 +469,9 @@ 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..8c7d593d45 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) @@ -31,9 +32,9 @@ 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: @@ -77,9 +78,9 @@ 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"} +https://github.com/Kotlin/kotlinx.coroutines/edit/master/docs/topics/ [//]: # (title: Composing suspending functions) @@ -60,9 +61,9 @@ 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: @@ -111,9 +112,9 @@ 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: @@ -164,9 +165,9 @@ 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 @@ -272,9 +273,9 @@ 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"} +https://github.com/Kotlin/kotlinx.coroutines/edit/master/docs/topics/ [//]: # (title: Coroutine context and dispatchers) @@ -43,9 +44,9 @@ 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): @@ -105,9 +106,9 @@ 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. @@ -191,9 +192,9 @@ 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 @@ -241,9 +242,9 @@ 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 @@ -276,9 +277,9 @@ 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: @@ -338,9 +339,9 @@ 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: @@ -380,9 +381,9 @@ 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: @@ -431,9 +432,9 @@ 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: @@ -465,9 +466,9 @@ 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: @@ -560,9 +561,9 @@ 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 @@ -615,9 +616,9 @@ 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..72af2c06ba 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) @@ -30,9 +31,9 @@ fun main() = runBlocking { // this: CoroutineScope ``` {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 ``` @@ -105,9 +106,9 @@ suspend fun doWorld() { ``` {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"} 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..0d369aa710 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.* @@ -52,9 +53,9 @@ 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-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.* @@ -112,9 +113,9 @@ 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: @@ -157,9 +158,9 @@ 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. @@ -219,9 +220,9 @@ 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: @@ -272,9 +273,9 @@ 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: @@ -322,9 +323,9 @@ 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: @@ -388,9 +389,9 @@ 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: @@ -438,9 +439,9 @@ 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: @@ -484,9 +485,9 @@ 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..a3cb1176c5 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) @@ -20,9 +21,9 @@ 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 from [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: @@ -53,9 +54,9 @@ 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 from [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. @@ -87,9 +88,9 @@ 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-03.kt). +> You can get the full code from [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. @@ -131,9 +132,9 @@ 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-04.kt). +> You can get the full code from [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 @@ -192,9 +193,9 @@ 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-05.kt). +> You can get the full code from [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: @@ -248,9 +249,9 @@ 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-06.kt). +> You can get the full code from [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: @@ -289,9 +290,9 @@ 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 from [here](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/test/guide/example-flow-07.kt). > -{type="note"} +{style="note"} +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 @@ -99,9 +100,9 @@ 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: @@ -194,9 +195,9 @@ 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: @@ -279,9 +280,9 @@ 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: @@ -363,9 +364,9 @@ 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: @@ -472,9 +473,9 @@ 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..1baf07d066 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) @@ -68,9 +69,9 @@ 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-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"}