Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 1.6.1 #3232

Merged
merged 30 commits into from Apr 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
0e96440
Upgraded SLF4J in eponymous integration module to 1.7.32 and updated …
severn-everett Jan 10, 2022
ed3445f
Improve Flow documentation (#3127)
qwwdfsad Jan 10, 2022
881cf68
Make multithreadingSupported a property with a getter (#3130)
ilmat192 Jan 11, 2022
a3f2491
Explicitly describe undispatched behaviour in runInterruptible (#3139)
qwwdfsad Jan 14, 2022
ce02a3f
Remove ignored test and its obsolete dependency with ASM 5.0 (#3140)
qwwdfsad Jan 17, 2022
9169d09
Rollback #2972, but leave a compatibility option with 1.6.0 (#3131)
qwwdfsad Jan 17, 2022
a1f5ab8
Optimization: resizable workers array (#3137)
elizarov Jan 17, 2022
f442001
Update code to prepare for nullness annotations in Guava (#3026)
cpovirk Jan 18, 2022
648f694
Prevent LimitedParallelismStressTest from allocating too much memory,…
qwwdfsad Jan 18, 2022
5e5dcd7
Integrate Kover (#3141)
qwwdfsad Jan 19, 2022
eac7bba
docs: typo in conflate docs (#3151)
krizzu Jan 21, 2022
3e7466a
Fix typo in CoroutineDispatcher documentation
qwwdfsad Jan 24, 2022
8136179
Fixing typo: `distinctUtilChanged` to `distinctUntilChanged` (#3154)
douglasmarques Jan 25, 2022
b5b254b
Fix example code in comment of CopyableThreadContextElement (#3157)
OliverO2 Jan 27, 2022
649d03e
Confine context-specific state to the thread in UndispatchedCoroutine…
qwwdfsad Feb 1, 2022
76989f7
Coverage: improve test coverage, disable deprecations, add missing te…
qwwdfsad Feb 1, 2022
ff80ba2
Introduce private DiagnosticCoroutineContextException and add it to t…
qwwdfsad Feb 1, 2022
70d0ec7
Update Dokka to 1.6.10 (#3184)
qwwdfsad Feb 11, 2022
ed09ff8
Update Kover to 0.5.0 (#3183)
qwwdfsad Feb 16, 2022
1029ad1
docs: Clarify MutableSharedFlow.emit/tryEmit on subscribers and overf…
elizarov Feb 16, 2022
70ae22b
Revert "Eagerly load CoroutineExceptionHandler and load corresponding…
qwwdfsad Feb 17, 2022
d5f852c
Provide a way to use CoroutineDispatcher as an Rx's Scheduler.
recheej Apr 19, 2020
83ffd17
Properly cleanup completion in SafeCollector to avoid unintended memo…
qwwdfsad Feb 24, 2022
b545807
Validate that throwing tryCopy does not crash with an internal error …
qwwdfsad Feb 24, 2022
f991742
docs: clarify section on coroutine memory consumption (#3225)
scolsen Mar 31, 2022
6c326e4
Do not mention service loading for CoroutineExceptionHandler as it is…
qwwdfsad Mar 31, 2022
8133c97
Fix limitedParallelism implementation on K/N (#3226)
qwwdfsad Mar 31, 2022
a5dd74b
CopyableThreadContextElement implementation (#3227)
qwwdfsad Apr 4, 2022
262876b
Merge branch 'master' into develop
qwwdfsad Apr 4, 2022
429b5d1
Version 1.6.1
qwwdfsad Apr 1, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGES.md
@@ -1,5 +1,19 @@
# Change log for kotlinx.coroutines

## Version 1.6.1

* Rollback of time-related functions dispatching on `Dispatchers.Main`.
This behavior was introduced in 1.6.0 and then found inconvenient and erroneous (#3106, #3113).
* Reworked the newly-introduced `CopyableThreadContextElement` to solve issues uncovered after the initial release (#3227).
* Fixed a bug with `ThreadLocalElement` not being properly updated in racy scenarios (#2930).
* Reverted eager loading of default `CoroutineExceptionHandler` that triggered ANR on some devices (#3180).
* New API to convert a `CoroutineDispatcher` to a Rx scheduler (#968, #548). Thanks @recheej!
* Fixed a memory leak with the very last element emitted from `flow` builder being retained in memory (#3197).
* Fixed a bug with `limitedParallelism` on K/N with new memory model throwing `ClassCastException` (#3223).
* `CoroutineContext` is added to the exception printed to the default `CoroutineExceptionHandler` to improve debuggability (#3153).
* Static memory consumption of `Dispatchers.Default` was significantly reduced (#3137).
* Updated slf4j version in `kotlinx-coroutines-slf4j` from 1.7.25 to 1.7.32.

## Version 1.6.0

Note that this is a full changelog relative to the 1.5.2 version. Changelog relative to 1.6.0-RC3 can be found at the end.
Expand Down
16 changes: 8 additions & 8 deletions README.md
Expand Up @@ -2,12 +2,12 @@

[![official JetBrains 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.6.0)](https://search.maven.org/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-core/1.6.0/pom)
[![Kotlin](https://img.shields.io/badge/kotlin-1.6.0-blue.svg?logo=kotlin)](http://kotlinlang.org)
[![Download](https://img.shields.io/maven-central/v/org.jetbrains.kotlinx/kotlinx-coroutines-core/1.6.1)](https://search.maven.org/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-core/1.6.1/pom)
[![Kotlin](https://img.shields.io/badge/kotlin-1.6.1-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/)

Library support for Kotlin coroutines with [multiplatform](#multiplatform) support.
This is a companion version for the Kotlin `1.6.0` release.
This is a companion version for the Kotlin `1.6.1` release.

```kotlin
suspend fun main() = coroutineScope {
Expand Down Expand Up @@ -83,7 +83,7 @@ Add dependencies (you can also add other modules that you need):
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-core</artifactId>
<version>1.6.0</version>
<version>1.6.1</version>
</dependency>
```

Expand All @@ -101,7 +101,7 @@ Add dependencies (you can also add other modules that you need):

```kotlin
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1")
}
```

Expand Down Expand Up @@ -131,7 +131,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.6.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1")
```

This gives you access to the Android [Dispatchers.Main]
Expand Down Expand Up @@ -166,7 +166,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.6.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1")
}
}
```
Expand All @@ -178,7 +178,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://search.maven.org/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-core-js/1.6.0/jar)
[`kotlinx-coroutines-core-js`](https://search.maven.org/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-core-js/1.6.1/jar)
(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
Expand Down
8 changes: 4 additions & 4 deletions build.gradle
Expand Up @@ -46,7 +46,6 @@ buildscript {
mavenCentral()
maven { url "https://plugins.gradle.org/m2/" }
maven { url "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev" }
maven { url 'https://maven.pkg.jetbrains.space/kotlin/p/dokka/dev' }
mavenLocal()
}

Expand All @@ -58,6 +57,7 @@ buildscript {
classpath "com.moowork.gradle:gradle-node-plugin:$gradle_node_version"
classpath "org.jetbrains.kotlinx:binary-compatibility-validator:$binary_compatibility_validator_version"
classpath "ru.vyarus:gradle-animalsniffer-plugin:1.5.3" // Android API check
classpath "org.jetbrains.kotlinx:kover:$kover_version"

// JMH plugins
classpath "com.github.jengelman.gradle.plugins:shadow:5.1.0"
Expand Down Expand Up @@ -105,7 +105,8 @@ allprojects {
}

apply plugin: "binary-compatibility-validator"
apply plugin: 'base'
apply plugin: "base"
apply plugin: "kover-conventions"

apiValidation {
ignoredProjects += unpublished + ["kotlinx-coroutines-bom"]
Expand All @@ -126,7 +127,6 @@ allprojects {
google()
mavenCentral()
maven { url "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev" }
maven { url 'https://maven.pkg.jetbrains.space/kotlin/p/dokka/dev' }
}
}

Expand Down Expand Up @@ -303,7 +303,7 @@ def publishTasks = getTasksByName("publish", true) + getTasksByName("publishNpm"

task deploy(dependsOn: publishTasks)

apply plugin: 'animalsniffer-convention'
apply plugin: "animalsniffer-conventions"

clean.dependsOn gradle.includedBuilds.collect { it.task(':clean') }

Expand Down
6 changes: 5 additions & 1 deletion buildSrc/build.gradle.kts
Expand Up @@ -19,7 +19,6 @@ repositories {
maven("https://plugins.gradle.org/m2")
}
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev")
maven("https://maven.pkg.jetbrains.space/kotlin/p/dokka/dev")
if (buildSnapshotTrain) {
mavenLocal()
}
Expand Down Expand Up @@ -60,4 +59,9 @@ dependencies {
exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib")
}
implementation("ru.vyarus:gradle-animalsniffer-plugin:1.5.3") // Android API check
implementation("org.jetbrains.kotlinx:kover:${version("kover")}") {
exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib-jdk8")
exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib-jdk7")
exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib")
}
}
1 change: 0 additions & 1 deletion buildSrc/settings.gradle.kts
Expand Up @@ -4,7 +4,6 @@
pluginManagement {
val build_snapshot_train: String? by settings
repositories {
maven(url = "https://maven.pkg.jetbrains.space/kotlin/p/dokka/dev/")
val cacheRedirectorEnabled = System.getenv("CACHE_REDIRECTOR")?.toBoolean() == true
if (cacheRedirectorEnabled) {
println("Redirecting repositories for buildSrc buildscript")
Expand Down
33 changes: 32 additions & 1 deletion buildSrc/src/main/kotlin/UnpackAar.kt
Expand Up @@ -2,18 +2,49 @@
* Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

import org.gradle.api.*
import org.gradle.api.artifacts.transform.InputArtifact
import org.gradle.api.artifacts.transform.TransformAction
import org.gradle.api.artifacts.transform.TransformOutputs
import org.gradle.api.artifacts.transform.TransformParameters
import org.gradle.api.attributes.*
import org.gradle.api.file.FileSystemLocation
import org.gradle.api.provider.Provider
import org.gradle.kotlin.dsl.*
import java.io.File
import java.nio.file.Files
import java.util.zip.ZipEntry
import java.util.zip.ZipFile

// TODO move back to kotlinx-coroutines-play-services when it's migrated to the kts
// Attributes used by aar dependencies
val artifactType = Attribute.of("artifactType", String::class.java)
val unpackedAar = Attribute.of("unpackedAar", Boolean::class.javaObjectType)

fun Project.configureAar() = configurations.configureEach {
afterEvaluate {
if (isCanBeResolved && !isCanBeConsumed) {
attributes.attribute(unpackedAar, true) // request all AARs to be unpacked
}
}
}

fun DependencyHandlerScope.configureAarUnpacking() {
attributesSchema {
attribute(unpackedAar)
}

artifactTypes {
create("aar") {
attributes.attribute(unpackedAar, false)
}
}

registerTransform(UnpackAar::class.java) {
from.attribute(unpackedAar, false).attribute(artifactType, "aar")
to.attribute(unpackedAar, true).attribute(artifactType, "jar")
}
}

@Suppress("UnstableApiUsage")
abstract class UnpackAar : TransformAction<TransformParameters.None> {
@get:InputArtifact
Expand Down
54 changes: 54 additions & 0 deletions buildSrc/src/main/kotlin/kover-conventions.gradle.kts
@@ -0,0 +1,54 @@
import kotlinx.kover.api.*
import kotlinx.kover.tasks.*

/*
* Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
apply(plugin = "kover")

val notCovered = sourceless + internal + unpublished

val expectedCoverage = mutableMapOf(
// These have lower coverage in general, it can be eventually fixed
"kotlinx-coroutines-swing" to 70, // awaitFrame is not tested
"kotlinx-coroutines-javafx" to 39, // JavaFx is not tested on TC because its graphic subsystem cannot be initialized in headless mode

// Reactor has lower coverage in general due to various fatal error handling features
"kotlinx-coroutines-reactor" to 75)

extensions.configure<KoverExtension> {
disabledProjects = notCovered
/*
* Is explicitly enabled on TC in a separate build step.
* Examples:
* ./gradlew :p:check -- doesn't verify coverage
* ./gradlew :p:check -Pkover.enabled=true -- verifies coverage
* ./gradlew :p:koverReport -Pkover.enabled=true -- generates report
*/
isDisabled = !(properties["kover.enabled"]?.toString()?.toBoolean() ?: false)
// TODO remove when updating Kover to version 0.5.x
intellijEngineVersion.set("1.0.657")
}

subprojects {
val projectName = name
if (projectName in notCovered) return@subprojects
tasks.withType<KoverVerificationTask> {
rule {
bound {
/*
* 85 is our baseline that we aim to raise to 90+.
* Missing coverage is typically due to bugs in the agent
* (e.g. signatures deprecated with an error are counted),
* sometimes it's various diagnostic `toString` or `catch` for OOMs/VerificationErrors,
* but some places are definitely worth visiting.
*/
minValue = expectedCoverage[projectName] ?: 85 // COVERED_LINES_PERCENTAGE
}
}
}

tasks.withType<KoverHtmlReportTask> {
htmlReportDir.set(file(rootProject.buildDir.toString() + "/kover/" + project.name + "/html"))
}
}
19 changes: 11 additions & 8 deletions docs/topics/coroutines-basics.md
Expand Up @@ -245,14 +245,17 @@ Done

<!--- TEST -->

## Coroutines ARE light-weight
## Coroutines are light-weight

Run the following code:
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
('.') while consuming very little memory:

```kotlin
import kotlinx.coroutines.*

//sampleStart
fun main() = runBlocking {
repeat(100_000) { // launch a lot of coroutines
launch {
Expand All @@ -261,19 +264,19 @@ fun main() = runBlocking {
}
}
}
//sampleEnd
```
<!-- While coroutines do have a smaller memory footprint than threads, this
example will exhaust the playground's heap memory; don't make it runnable. -->

> 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) -->

It launches 100K coroutines and, after 5 seconds, each coroutine prints a dot.

Now, try that with threads (remove `runBlocking`, replace `launch` with `thread`, and replace `delay` with `Thread.sleep`).
What would happen? (Most likely your code will produce some sort of out-of-memory error)
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.

<!--- MODULE kotlinx-coroutines-core -->
<!--- INDEX kotlinx.coroutines -->
Expand Down
6 changes: 0 additions & 6 deletions docs/topics/exception-handling.md
Expand Up @@ -75,12 +75,6 @@ You cannot recover from the exception in the `CoroutineExceptionHandler`. The co
with the corresponding exception when the handler is called. Normally, the handler is used to
log the exception, show some kind of error message, terminate, and/or restart the application.

On JVM it is possible to redefine global exception handler for all coroutines by registering [CoroutineExceptionHandler] via
[`ServiceLoader`](https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html).
Global exception handler is similar to
[`Thread.defaultUncaughtExceptionHandler`](https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#setDefaultUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler))
which is used when no more specific handlers are registered.
On Android, `uncaughtExceptionPreHandler` is installed as a global coroutine exception handler.

`CoroutineExceptionHandler` is invoked only on **uncaught** exceptions &mdash; exceptions that were not handled in any other way.
In particular, all _children_ coroutines (coroutines created in the context of another [Job]) delegate handling of
Expand Down
9 changes: 5 additions & 4 deletions gradle.properties
Expand Up @@ -3,7 +3,7 @@
#

# Kotlin
version=1.6.0-SNAPSHOT
version=1.6.1-SNAPSHOT
group=org.jetbrains.kotlinx
kotlin_version=1.6.0

Expand All @@ -14,22 +14,23 @@ atomicfu_version=0.17.0
knit_version=0.3.0
html_version=0.7.2
lincheck_version=2.14
dokka_version=1.6.0-dev-138
dokka_version=1.6.10
byte_buddy_version=1.10.9
reactor_version=3.4.1
reactive_streams_version=1.0.3
rxjava2_version=2.2.8
rxjava3_version=3.0.2
javafx_version=11.0.2
javafx_plugin_version=0.0.8
binary_compatibility_validator_version=0.8.0-RC
binary_compatibility_validator_version=0.8.0
kover_version=0.5.0
blockhound_version=1.0.2.RELEASE
jna_version=5.9.0

# Android versions
android_version=4.1.1.4
androidx_annotation_version=1.1.0
robolectric_version=4.0.2
robolectric_version=4.4
baksmali_version=2.2.7

# JS
Expand Down
6 changes: 1 addition & 5 deletions gradle/dokka.gradle.kts
Expand Up @@ -37,7 +37,7 @@ tasks.withType(DokkaTaskPartial::class).configureEach {
packageListUrl.set(rootProject.projectDir.toPath().resolve("site/stdlib.package.list").toUri().toURL())
}

if (project.name != "kotlinx-coroutines-core" && project.name != "kotlinx-coroutines-test") {
if (!project.isMultiplatform) {
dependsOn(project.configurations["compileClasspath"])
doFirst {
// resolve classpath only during execution
Expand Down Expand Up @@ -66,10 +66,6 @@ if (project.name == "kotlinx-coroutines-core") {
val jvmMain by getting {
makeLinkMapping(project.file("jvm"))
}

configureEach {
classpath.from(project.configurations["jvmCompileClasspath"].files)
}
}
}
}
2 changes: 1 addition & 1 deletion integration/kotlinx-coroutines-guava/README.md
Expand Up @@ -62,6 +62,6 @@ Integration with Guava [ListenableFuture](https://github.com/google/guava/wiki/L

<!--- INDEX com.google.common.util.concurrent -->

[com.google.common.util.concurrent.ListenableFuture]: https://kotlin.github.io/kotlinx.coroutines/https://google.github.io/guava/releases/28.0-jre/api/docs/com/google/common/util/concurrent/ListenableFuture.html
[com.google.common.util.concurrent.ListenableFuture]: https://kotlin.github.io/kotlinx.coroutines/https://google.github.io/guava/releases/31.0.1-jre/api/docs/com/google/common/util/concurrent/ListenableFuture.html

<!--- END -->
7 changes: 6 additions & 1 deletion integration/kotlinx-coroutines-guava/build.gradle.kts
Expand Up @@ -2,12 +2,17 @@
* Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

val guavaVersion = "28.0-jre"
val guavaVersion = "31.0.1-jre"

dependencies {
compile("com.google.guava:guava:$guavaVersion")
}

java {
targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_1_8
}

externalDocumentationLink(
url = "https://google.github.io/guava/releases/$guavaVersion/api/docs/"
)