Skip to content

Commit

Permalink
Merge pull request #3232 from Kotlin/version-1.6.1
Browse files Browse the repository at this point in the history
Version 1.6.1
  • Loading branch information
qwwdfsad committed Apr 4, 2022
2 parents 0d26d6c + 429b5d1 commit 2c3435c
Show file tree
Hide file tree
Showing 81 changed files with 2,646 additions and 493 deletions.
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/"
)

0 comments on commit 2c3435c

Please sign in to comment.