diff --git a/CHANGES.md b/CHANGES.md index 1ed133f612..4ac7156672 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,10 @@ # Change log for kotlinx.coroutines +## Version 1.7.3 + +* Disabled the publication of the multiplatform library metadata for the old (1.6 and earlier) KMP Gradle plugin (#3809). +* Fixed a bug introduced in 1.7.2 that disabled the coroutine debugger in IDEA (#3822). + ## Version 1.7.2 ### Bug fixes and improvements diff --git a/README.md b/README.md index bb771cdd35..8f89a6df2d 100644 --- a/README.md +++ b/README.md @@ -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.2)](https://central.sonatype.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-core/1.7.2) +[![Download](https://img.shields.io/maven-central/v/org.jetbrains.kotlinx/kotlinx-coroutines-core/1.7.3)](https://central.sonatype.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-core/1.7.3) [![Kotlin](https://img.shields.io/badge/kotlin-1.9.21-blue.svg?logo=kotlin)](http://kotlinlang.org) [![Slack channel](https://img.shields.io/badge/chat-slack-green.svg?logo=slack)](https://kotlinlang.slack.com/messages/coroutines/) @@ -26,7 +26,7 @@ suspend fun main() = coroutineScope { * [core](kotlinx-coroutines-core/README.md) — common coroutines across all platforms: * [launch] and [async] coroutine builders returning [Job] and [Deferred] light-weight futures with cancellation support; - * [Dispatchers] object with [Main][Dispatchers.Main] dispatcher for Android/Swing/JavaFx, and [Default][Dispatchers.Default] dispatcher for background coroutines; + * [Dispatchers] object with [Main][Dispatchers.Main] dispatcher for Android/Swing/JavaFx (which require the corresponding artifacts in runtime) and Darwin (included out of the box), and [Default][Dispatchers.Default] dispatcher for background coroutines; * [delay] and [yield] top-level suspending functions; * [Flow] — cold asynchronous stream with [flow][_flow] builder and comprehensive operator set ([filter], [map], etc); * [Channel], [Mutex], and [Semaphore] communication and synchronization primitives; @@ -36,7 +36,7 @@ suspend fun main() = coroutineScope { * [select] expression support and more. * [core/jvm](kotlinx-coroutines-core/jvm/) — additional core features available on Kotlin/JVM: * [Dispatchers.IO] dispatcher for blocking coroutines; - * [Executor.asCoroutineDispatcher][asCoroutineDispatcher] extension, custom thread pools, and more. + * [Executor.asCoroutineDispatcher][asCoroutineDispatcher] extension, custom thread pools, and more; * Integrations with `CompletableFuture` and JVM-specific extensions. * [core/js](kotlinx-coroutines-core/js/) — additional core features available on Kotlin/JS: * Integration with `Promise` via [Promise.await] and [promise] builder; @@ -54,7 +54,7 @@ suspend fun main() = coroutineScope { * RxJava 2.x ([rxFlowable], [rxSingle], etc), and * RxJava 3.x ([rxFlowable], [rxSingle], etc), and * Project Reactor ([flux], [mono], etc). -* [ui](ui/README.md) — modules that provide coroutine dispatchers for various single-threaded UI libraries: +* [ui](ui/README.md) — modules that provide the [Main][Dispatchers.Main] dispatcher for various single-threaded UI libraries: * Android, JavaFX, and Swing. * [integration](integration/README.md) — modules that provide integration with various asynchronous callback- and future-based libraries: * Guava [ListenableFuture.await], and Google Play Services [Task.await]; @@ -85,7 +85,7 @@ Add dependencies (you can also add other modules that you need): org.jetbrains.kotlinx kotlinx-coroutines-core - 1.7.2 + 1.7.3 ``` @@ -103,7 +103,7 @@ Add dependencies (you can also add other modules that you need): ```kotlin dependencies { - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.2") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") } ``` @@ -133,7 +133,7 @@ Add [`kotlinx-coroutines-android`](ui/kotlinx-coroutines-android) module as a dependency when using `kotlinx.coroutines` on Android: ```kotlin -implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.2") +implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3") ``` This gives you access to the Android [Dispatchers.Main] @@ -168,7 +168,7 @@ In common code that should get compiled for different platforms, you can add a d ```kotlin commonMain { dependencies { - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.2") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") } } ``` @@ -180,7 +180,7 @@ 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://central.sonatype.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-core-js/1.7.2) +[`kotlinx-coroutines-core-js`](https://central.sonatype.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-core-js/1.7.3) (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 diff --git a/docs/topics/composing-suspending-functions.md b/docs/topics/composing-suspending-functions.md index 8ed7336199..e1255c8d07 100644 --- a/docs/topics/composing-suspending-functions.md +++ b/docs/topics/composing-suspending-functions.md @@ -189,6 +189,12 @@ standard `lazy` function in cases when computation of the value involves suspend ## Async-style functions +> This programming style with async functions is provided here only for illustration, because it is a popular style +> in other programming languages. Using this style with Kotlin coroutines is **strongly discouraged** for the +> reasons explained below. +> +{type="note"} + We can define async-style functions that invoke `doSomethingUsefulOne` and `doSomethingUsefulTwo` _asynchronously_ using the [async] coroutine builder using a [GlobalScope] reference to opt-out of the structured concurrency. @@ -275,12 +281,6 @@ The answer is 42 Completed in 1085 ms --> -> This programming style with async functions is provided here only for illustration, because it is a popular style -> in other programming languages. Using this style with Kotlin coroutines is **strongly discouraged** for the -> reasons explained below. -> -{type="note"} - Consider what happens if between the `val one = somethingUsefulOneAsync()` line and `one.await()` expression there is some logic error in the code, and the program throws an exception, and the operation that was being performed by the program aborts. Normally, a global error-handler could catch this exception, log and report the error for developers, but the program diff --git a/docs/topics/coroutine-context-and-dispatchers.md b/docs/topics/coroutine-context-and-dispatchers.md index 32d1891955..969bd21eb9 100644 --- a/docs/topics/coroutine-context-and-dispatchers.md +++ b/docs/topics/coroutine-context-and-dispatchers.md @@ -239,10 +239,9 @@ fun main() { } } } -//sampleEnd +//sampleEnd } ``` -{kotlin-runnable="true" kotlin-min-compiler-version="1.3"} > You can get the full code [here](../../kotlinx-coroutines-core/jvm/test/guide/example-context-04.kt). > diff --git a/docs/topics/coroutines-basics.md b/docs/topics/coroutines-basics.md index d7d6700342..8a5b4304ad 100644 --- a/docs/topics/coroutines-basics.md +++ b/docs/topics/coroutines-basics.md @@ -6,7 +6,7 @@ This section covers basic coroutine concepts. ## Your first coroutine -A _coroutine_ is an instance of suspendable computation. It is conceptually similar to a thread, in the sense that it +A _coroutine_ is an instance of a suspendable computation. It is conceptually similar to a thread, in the sense that it takes a block of code to run that works concurrently with the rest of the code. However, a coroutine is not bound to any particular thread. It may suspend its execution in one thread and resume in another one. diff --git a/docs/topics/exception-handling.md b/docs/topics/exception-handling.md index 8bf8c106ca..ab1ec6a49a 100644 --- a/docs/topics/exception-handling.md +++ b/docs/topics/exception-handling.md @@ -9,7 +9,7 @@ coroutine throw an exception. ## Exception propagation -Coroutine builders come in two flavors: propagating exceptions automatically ([launch] and [actor]) or +Coroutine builders come in two flavors: propagating exceptions automatically ([launch]) or exposing them to users ([async] and [produce]). When these builders are used to create a _root_ coroutine, that is not a _child_ of another coroutine, the former builders treat exceptions as **uncaught** exceptions, similar to Java's `Thread.uncaughtExceptionHandler`, @@ -276,10 +276,6 @@ fun main() = runBlocking { > {type="note"} -> Note: This above code will work properly only on JDK7+ that supports `suppressed` exceptions -> -{type="note"} - The output of this code is: ```text @@ -306,7 +302,7 @@ fun main() = runBlocking { println("CoroutineExceptionHandler got $exception") } val job = GlobalScope.launch(handler) { - val inner = launch { // all this stack of coroutines will get cancelled + val innerJob = launch { // all this stack of coroutines will get cancelled launch { launch { throw IOException() // the original exception @@ -314,7 +310,7 @@ fun main() = runBlocking { } } try { - inner.join() + innerJob.join() } catch (e: CancellationException) { println("Rethrowing CancellationException with original cause") throw e // cancellation exception is rethrown, yet the original IOException gets to the handler @@ -523,7 +519,6 @@ The scope is completed -[actor]: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/actor.html [produce]: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/produce.html [ReceiveChannel.receive]: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-receive-channel/receive.html diff --git a/gradle.properties b/gradle.properties index 2d57149b5d..6d46042046 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ # # Kotlin -version=1.7.2-SNAPSHOT +version=1.7.3-SNAPSHOT group=org.jetbrains.kotlinx kotlin_version=1.9.21 @@ -11,7 +11,7 @@ kotlin_version=1.9.21 junit_version=4.12 junit5_version=5.7.0 atomicfu_version=0.23.1 -knit_version=0.4.0 +knit_version=0.5.0-Beta html_version=0.7.2 lincheck_version=2.18.1 dokka_version=1.8.10 diff --git a/gradle/dokka.gradle.kts b/gradle/dokka.gradle.kts index 829faad0a0..b02d86106d 100644 --- a/gradle/dokka.gradle.kts +++ b/gradle/dokka.gradle.kts @@ -9,14 +9,6 @@ import java.net.* apply() //apply() -fun GradleDokkaSourceSetBuilder.makeLinkMapping(projectDir: File) { - sourceLink { - val relPath = rootProject.projectDir.toPath().relativize(projectDir.toPath()) - localDirectory.set(projectDir.resolve("src")) - remoteUrl.set(URL("https://github.com/kotlin/kotlinx.coroutines/tree/master/$relPath/src")) - remoteLineSuffix.set("#L") - } -} val knit_version: String by project tasks.withType(DokkaTaskPartial::class).configureEach { @@ -45,31 +37,31 @@ tasks.withType(DokkaTaskPartial::class).configureEach { } } -val kotlin_version: String by project +fun GradleDokkaSourceSetBuilder.makeLinkMapping(projectDir: File) { + sourceLink { + val relPath = rootProject.projectDir.toPath().relativize(projectDir.toPath()) + localDirectory.set(projectDir.resolve("src")) + remoteUrl.set(URL("https://github.com/kotlin/kotlinx.coroutines/tree/master/$relPath/src")) + remoteLineSuffix.set("#L") + } +} -if (project.name == "kotlinx-coroutines-core") { - // Custom configuration for MPP modules +if (project.isMultiplatform) { + // Configuration for MPP modules tasks.withType(DokkaTaskPartial::class).configureEach { - dokkaSourceSets { - val commonMain by getting { - makeLinkMapping(project.file("common")) - } - - val nativeMain by getting { - makeLinkMapping(project.file("native")) - } - - val jsMain by getting { - makeLinkMapping(project.file("js")) - } - - val jvmMain by getting { - makeLinkMapping(project.file("jvm")) - } - - val wasmJsMain by getting { - makeLinkMapping(project.file("wasm")) - } + // sources in MPP are located in moduleDir/PLATFORM/src, + // where PLATFORM could be jvm, js, jdk8, concurrent, etc + // configuration happens in buildSrc/src/main/kotlin/SourceSetsKt.configureMultiplatform + dokkaSourceSets.matching { it.name.endsWith("Main") }.configureEach { + val platform = name.dropLast(4) + makeLinkMapping(project.file(platform)) + } + } +} else { + // Configuration for JVM modules + tasks.withType(DokkaTaskPartial::class).configureEach { + dokkaSourceSets.named("main") { + makeLinkMapping(projectDir) } } } diff --git a/integration-testing/gradle.properties b/integration-testing/gradle.properties index e8e17351cf..5cc832137e 100644 --- a/integration-testing/gradle.properties +++ b/integration-testing/gradle.properties @@ -1,5 +1,5 @@ kotlin_version=1.9.21 -coroutines_version=1.7.2-SNAPSHOT +coroutines_version=1.7.3-SNAPSHOT asm_version=9.3 kotlin.code.style=official diff --git a/kotlinx-coroutines-core/common/src/CoroutineScope.kt b/kotlinx-coroutines-core/common/src/CoroutineScope.kt index b0928d5c58..cf4c1cfc03 100644 --- a/kotlinx-coroutines-core/common/src/CoroutineScope.kt +++ b/kotlinx-coroutines-core/common/src/CoroutineScope.kt @@ -90,7 +90,7 @@ public interface CoroutineScope { * Adds the specified coroutine context to this scope, overriding existing elements in the current * scope's context with the corresponding keys. * - * This is a shorthand for `CoroutineScope(thisScope + context)`. + * This is a shorthand for `CoroutineScope(thisScope.coroutineContext + context)`. */ public operator fun CoroutineScope.plus(context: CoroutineContext): CoroutineScope = ContextScope(coroutineContext + context) @@ -226,7 +226,7 @@ public object GlobalScope : CoroutineScope { * The provided scope inherits its [coroutineContext][CoroutineScope.coroutineContext] from the outer scope, but overrides * the context's [Job]. * - * This function is designed for _parallel decomposition_ of work. When any child coroutine in this scope fails, + * This function is designed for _concurrent decomposition_ of work. When any child coroutine in this scope fails, * this scope fails and all the rest of the children are cancelled (for a different behavior see [supervisorScope]). * This function returns as soon as the given block and all its children coroutines are completed. * A usage example of a scope looks like this: diff --git a/kotlinx-coroutines-core/common/src/Dispatchers.common.kt b/kotlinx-coroutines-core/common/src/Dispatchers.common.kt index bb85d869cc..cf7a23a1ea 100644 --- a/kotlinx-coroutines-core/common/src/Dispatchers.common.kt +++ b/kotlinx-coroutines-core/common/src/Dispatchers.common.kt @@ -31,13 +31,13 @@ public expect object Dispatchers { * [`ServiceLoader`](https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html). * - On JS it is equivalent to the [Default] dispatcher with [immediate][MainCoroutineDispatcher.immediate] support. * - On Native Darwin-based targets, it is a dispatcher backed by Darwin's main queue. - * - On other Native targets, it is a single-threaded dispatcher backed by a standalone worker. + * - On other Native targets, it is not available. + * - `Dispatchers.setMain` from the `kotlinx-coroutines-test` artifact can replace the main dispatcher with a mock one for testing. * - * In order to work with the `Main` dispatcher, the following artifact should be added to the project runtime dependencies: + * In order to work with the `Main` dispatcher on the JVM, the following artifact should be added to the project runtime dependencies: * - `kotlinx-coroutines-android` — for Android Main thread dispatcher * - `kotlinx-coroutines-javafx` — for JavaFx Application thread dispatcher * - `kotlinx-coroutines-swing` — for Swing EDT dispatcher - * - `kotlinx-coroutines-test` — for mocking the `Main` dispatcher in tests via `Dispatchers.setMain` */ public val Main: MainCoroutineDispatcher diff --git a/kotlinx-coroutines-core/jvm/test/guide/example-exceptions-06.kt b/kotlinx-coroutines-core/jvm/test/guide/example-exceptions-06.kt index bc9f77b936..c1374f787c 100644 --- a/kotlinx-coroutines-core/jvm/test/guide/example-exceptions-06.kt +++ b/kotlinx-coroutines-core/jvm/test/guide/example-exceptions-06.kt @@ -14,7 +14,7 @@ fun main() = runBlocking { println("CoroutineExceptionHandler got $exception") } val job = GlobalScope.launch(handler) { - val inner = launch { // all this stack of coroutines will get cancelled + val innerJob = launch { // all this stack of coroutines will get cancelled launch { launch { throw IOException() // the original exception @@ -22,7 +22,7 @@ fun main() = runBlocking { } } try { - inner.join() + innerJob.join() } catch (e: CancellationException) { println("Rethrowing CancellationException with original cause") throw e // cancellation exception is rethrown, yet the original IOException gets to the handler diff --git a/kotlinx-coroutines-debug/README.md b/kotlinx-coroutines-debug/README.md index 104dde323a..5e385e3c24 100644 --- a/kotlinx-coroutines-debug/README.md +++ b/kotlinx-coroutines-debug/README.md @@ -61,7 +61,7 @@ stacktraces will be dumped to the console. ### Using as JVM agent Debug module can also be used as a standalone JVM agent to enable debug probes on the application startup. -You can run your application with an additional argument: `-javaagent:kotlinx-coroutines-debug-1.7.2.jar`. +You can run your application with an additional argument: `-javaagent:kotlinx-coroutines-debug-1.7.3.jar`. Additionally, on Linux and Mac OS X you can use `kill -5 $pid` command in order to force your application to print all alive coroutines. When used as Java agent, `"kotlinx.coroutines.debug.enable.creation.stack.trace"` system property can be used to control [DebugProbes.enableCreationStackTraces] along with agent startup. diff --git a/kotlinx-coroutines-test/README.md b/kotlinx-coroutines-test/README.md index aa0606d5d2..f5dd8e6cb5 100644 --- a/kotlinx-coroutines-test/README.md +++ b/kotlinx-coroutines-test/README.md @@ -26,7 +26,7 @@ Provided [TestDispatcher] implementations: Add `kotlinx-coroutines-test` to your project test dependencies: ``` dependencies { - testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.2' + testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3' } ``` diff --git a/ui/coroutines-guide-ui.md b/ui/coroutines-guide-ui.md index 3d11254e17..872926d713 100644 --- a/ui/coroutines-guide-ui.md +++ b/ui/coroutines-guide-ui.md @@ -110,7 +110,7 @@ Add dependencies on `kotlinx-coroutines-android` module to the `dependencies { . `app/build.gradle` file: ```groovy -implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.2" +implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3" ``` You can clone [kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) project from GitHub onto your