Skip to content

Commit

Permalink
Merge branch 'master' into develop
Browse files Browse the repository at this point in the history
# Conflicts:
#	README.md
  • Loading branch information
qwwdfsad committed Apr 18, 2023
2 parents 915347c + 2653cd2 commit b0c510c
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 37 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![Kotlin Stable](https://kotl.in/badges/stable.svg)](https://kotlinlang.org/docs/components-stability.html)
[![JetBrains official project](https://jb.gg/badges/official.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
[![GitHub license](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0)
[![Download](https://img.shields.io/maven-central/v/org.jetbrains.kotlinx/kotlinx-coroutines-core/1.7.0-Beta)](https://search.maven.org/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-core/1.7.0-Beta/pom)
[![Download](https://img.shields.io/maven-central/v/org.jetbrains.kotlinx/kotlinx-coroutines-core/1.7.0-Beta)](https://central.sonatype.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-core/1.7.0-Beta)
[![Kotlin](https://img.shields.io/badge/kotlin-1.8.20-blue.svg?logo=kotlin)](http:https://kotlinlang.org)
[![Slack channel](https://img.shields.io/badge/chat-slack-green.svg?logo=slack)](https://kotlinlang.slack.com/messages/coroutines/)

Expand Down Expand Up @@ -180,13 +180,13 @@ Platform-specific dependencies are recommended to be used only for non-multiplat
#### JS

Kotlin/JS version of `kotlinx.coroutines` is published as
[`kotlinx-coroutines-core-js`](https://search.maven.org/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-core-js/1.7.0-Beta/jar)
[`kotlinx-coroutines-core-js`](https://central.sonatype.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-core-js/1.7.0-Beta)
(follow the link to get the dependency declaration snippet) and as [`kotlinx-coroutines-core`](https://www.npmjs.com/package/kotlinx-coroutines-core) NPM package.

#### Native

Kotlin/Native version of `kotlinx.coroutines` is published as
[`kotlinx-coroutines-core-$platform`](https://mvnrepository.com/search?q=kotlinx-coroutines-core-) where `$platform` is
[`kotlinx-coroutines-core-$platform`](https://central.sonatype.com/search?q=kotlinx-coroutines-core&namespace=org.jetbrains.kotlinx) where `$platform` is
the target Kotlin/Native platform.
Targets are provided in accordance with [official K/N target support](https://kotlinlang.org/docs/native-target-support.html).
## Building and Contributing
Expand Down
2 changes: 1 addition & 1 deletion docs/topics/cancellation-and-timeouts.md
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ fun main() {
If you run the above code, you'll see that it does not always print zero, though it may depend on the timings
of your machine. You may need to tweak the timeout in this example to actually see non-zero values.

> Note that incrementing and decrementing `acquired` counter here from 100K coroutines is completely thread-safe,
> Note that incrementing and decrementing `acquired` counter here from 10K coroutines is completely thread-safe,
> 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.
>
Expand Down
53 changes: 28 additions & 25 deletions docs/topics/coroutines-and-channels.md
Original file line number Diff line number Diff line change
Expand Up @@ -870,13 +870,33 @@ completion or cancel it explicitly, but that won't happen automatically as it wo

### Canceling the loading of contributors

Consider two versions of the `loadContributorsConcurrent()` function. The first uses `coroutineScope` to start all of the
child coroutines, whereas the second uses `GlobalScope`. Compare how both versions behave when you try to cancel
the parent coroutine.
Create two versions of the function that loads the list of contributors. Compare how both versions behave when you try to
cancel the parent coroutine. The first version will use `coroutineScope` to start all of the child coroutines,
whereas the second will use `GlobalScope`.

1. In `Request5Concurrent.kt`, add a 3-second delay to the `loadContributorsConcurrent()` function:

```kotlin
suspend fun loadContributorsConcurrent(
service: GitHubService,
req: RequestData
): List<User> = coroutineScope {
// ...
async {
log("starting loading for ${repo.name}")
delay(3000)
// load repo contributors
}
// ...
}
```

The delay affects all of the coroutines that send requests, so that there's enough time to cancel the loading
after the coroutines are started but before the requests are sent.

1. Copy the implementation of `loadContributorsConcurrent()` from `Request5Concurrent.kt` to
`loadContributorsNotCancellable()` in `Request5NotCancellable.kt`, and then remove the creation of a new `coroutineScope`.
2. The `async` calls now fail to resolve, so start them by using `GlobalScope.async`:
2. Create the second version of the loading function: copy the implementation of `loadContributorsConcurrent()` to
`loadContributorsNotCancellable()` in `Request5NotCancellable.kt` and then remove the creation of a new `coroutineScope`.
3. The `async` calls now fail to resolve, so start them by using `GlobalScope.async`:

```kotlin
suspend fun loadContributorsNotCancellable(
Expand All @@ -894,25 +914,8 @@ the parent coroutine.
```

* The function now returns the result directly, not as the last expression inside the lambda (lines `#1` and `#3`).
* All of the "contributors" coroutines are started inside the `GlobalScope`, not as children of the coroutine scope (
line `#2`).
3. Add a 3-second delay to all of the coroutines that send requests, so that there's enough time to cancel the loading
after the coroutines are started but before the requests are sent:

```kotlin
suspend fun loadContributorsConcurrent(
service: GitHubService,
req: RequestData
): List<User> = coroutineScope {
// ...
async {
log("starting loading for ${repo.name}")
delay(3000)
// load repo contributors
}
// ...
}
```
* All of the "contributors" coroutines are started inside the `GlobalScope`, not as children of the coroutine scope
(line `#2`).

4. Run the program and choose the _CONCURRENT_ option to load the contributors.
5. Wait until all of the "contributors" coroutines are started, and then click _Cancel_. The log shows no new results,
Expand Down
13 changes: 7 additions & 6 deletions docs/topics/coroutines-basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,33 +250,34 @@ Done
Coroutines are less resource-intensive than JVM threads. Code that exhausts the
JVM's available memory when using threads can be expressed using coroutines
without hitting resource limits. For example, the following code launches
100000 distinct coroutines that each wait 5 seconds and then print a period
50,000 distinct coroutines that each waits 5 seconds and then prints a period
('.') while consuming very little memory:

```kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
repeat(100_000) { // launch a lot of coroutines
repeat(50_000) { // launch a lot of coroutines
launch {
delay(5000L)
print(".")
}
}
}
```
<!-- While coroutines do have a smaller memory footprint than threads, this
example will exhaust the playground's heap memory; don't make it runnable. -->
{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).
>
{type="note"}

<!--- TEST lines.size == 1 && lines[0] == ".".repeat(100_000) -->
<!--- TEST lines.size == 1 && lines[0] == ".".repeat(50_000) -->

If you write the same program using threads (remove `runBlocking`, replace
`launch` with `thread`, and replace `delay` with `Thread.sleep`), it will
likely consume too much memory and throw an out-of-memory error.
consume a lot of memory. Depending on your operating system, JDK version,
and its settings, it will either throw an out-of-memory error or start threads slowly
so that there are never too many concurrently running threads.

<!--- MODULE kotlinx-coroutines-core -->
<!--- INDEX kotlinx.coroutines -->
Expand Down
2 changes: 1 addition & 1 deletion kotlinx-coroutines-core/jvm/test/guide/example-basic-06.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ package kotlinx.coroutines.guide.exampleBasic06
import kotlinx.coroutines.*

fun main() = runBlocking {
repeat(100_000) { // launch a lot of coroutines
repeat(50_000) { // launch a lot of coroutines
launch {
delay(5000L)
print(".")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class BasicsGuideTest {
@Test
fun testExampleBasic06() {
test("ExampleBasic06") { kotlinx.coroutines.guide.exampleBasic06.main() }.also { lines ->
check(lines.size == 1 && lines[0] == ".".repeat(100_000))
check(lines.size == 1 && lines[0] == ".".repeat(50_000))
}
}
}

0 comments on commit b0c510c

Please sign in to comment.