Library support for Kotlin coroutines

Overview

kotlinx.coroutines

official JetBrains project GitHub license Download Kotlin Slack channel

Library support for Kotlin coroutines with multiplatform support. This is a companion version for the Kotlin 1.6.0 release.

suspend fun main() = coroutineScope {
    launch { 
       delay(1000)
       println("Kotlin Coroutines World!") 
    }
    println("Hello")
}

Play with coroutines online here

Modules

Documentation

Using in your projects

Maven

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-RC3</version>
</dependency>

And make sure that you use the latest Kotlin version:

<properties>
    <kotlin.version>1.6.0</kotlin.version>
</properties>

Gradle

Add dependencies (you can also add other modules that you need):

dependencies {
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0-RC3'
}

And make sure that you use the latest Kotlin version:

buildscript {
    ext.kotlin_version = '1.6.0'
}

Make sure that you have mavenCentral() in the list of repositories:

repository {
    mavenCentral()
}

Gradle Kotlin DSL

Add dependencies (you can also add other modules that you need):

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

And make sure that you use the latest Kotlin version:

plugins {
    kotlin("jvm") version "1.5.30"
}

Make sure that you have mavenCentral() in the list of repositories.

Android

Add kotlinx-coroutines-android module as a dependency when using kotlinx.coroutines on Android:

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0-RC3'

This gives you access to the Android Dispatchers.Main coroutine dispatcher and also makes sure that in case of a crashed coroutine with an unhandled exception that this exception is logged before crashing the Android application, similarly to the way uncaught exceptions in threads are handled by the Android runtime.

R8 and ProGuard

R8 and ProGuard rules are bundled into the kotlinx-coroutines-android module. For more details see "Optimization" section for Android.

Avoiding including the debug infrastructure in the resulting APK

The kotlinx-coroutines-core artifact contains a resource file that is not required for the coroutines to operate normally and is only used by the debugger. To exclude it at no loss of functionality, add the following snippet to the android block in your Gradle file for the application subproject:

packagingOptions {
    resources.excludes += "DebugProbesKt.bin"
}

Multiplatform

Core modules of kotlinx.coroutines are also available for Kotlin/JS and Kotlin/Native.

In common code that should get compiled for different platforms, you can add a dependency to kotlinx-coroutines-core right to the commonMain source set:

commonMain {
    dependencies {
        implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0-RC3")
    }
}

No more additional dependencies are needed, platform-specific artifacts will be resolved automatically via Gradle metadata available since Gradle 5.3.

Platform-specific dependencies are recommended to be used only for non-multiplatform projects that are compiled only for target platform.

JS

Kotlin/JS version of kotlinx.coroutines is published as kotlinx-coroutines-core-js (follow the link to get the dependency declaration snippet) and as kotlinx-coroutines-core NPM package.

Native

Kotlin/Native version of kotlinx.coroutines is published as kotlinx-coroutines-core-$platform where $platform is the target Kotlin/Native platform. List of currently supported targets.

Only single-threaded code (JS-style) on Kotlin/Native is supported in stable versions. Additionally, a special -native-mt version is released on a regular basis, for the state of multi-threaded coroutines support please follow the corresponding issue for the additional details.

Since Kotlin/Native does not generally provide binary compatibility between versions, you should use the same version of the Kotlin/Native compiler as was used to build kotlinx.coroutines.

Building and Contributing

See Contributing Guidelines.

Comments
  • Support multi-threaded coroutines on Kotlin/Native

    Support multi-threaded coroutines on Kotlin/Native

    You can have multiple threads in Kotlin/Native. ~Each thread can have its own event loop with runBlocking and have number of coroutines running there~. Currently communication between those threads via coroutine primitives (like channels) is not supported. This issue it to track enhancement of Kotlin/Native in kotlinx.coroutines library so that all the following becomes possible:

    • Launching coroutines from one thread with a dispatcher on another thread
    • Await/join coroutine running on another thread
    • Send/Receive elements to/from coroutines on other threads

    UPDATE: Currently, coroutines are supported only on the main thread. You cannot have coroutines off the main thread due to the way the library is currently structured.

    UPDATE 2: the separate library version that supports Kotlin/Native multithreading is released on a regular basis. For the details and limitations, please follow kotlin-native-sharing.md document. The latest version: 1.5.2-native-mt

    enhancement native 
    opened by elizarov 155
  • Provide abstraction for cold streams

    Provide abstraction for cold streams

    All the currently provided channel abstractions in kotlinx.coroutines are hot. The data is being produced regardless of the presence of subscriber. This is good for data sources and applications that are inherently hot, like incoming network and UI-events.

    However, hot streams are not an ideal solution for cases where data stream is produced on demand. Consider, for example, the following simple code that produces ReceiveChannel<Int>:

    produce<Int> { 
        while (true) {
            val x = computeNextValue()
            send(x)
        } 
    }
    

    One obvious downside is the computeNextValue() is invoked before send, so even when receiver is not ready, the next value gets computed. Of course, it gets suspended in send if there is no receiver, but it is not as lazy as you get with cold reactive Publisher/Observable/Flowable/Flux/Flow.

    We need the abstraction for cold streams in kotlinx.coroutines that is going to be just as lazy, computing data in "push" mode versus "pull" mode of hot channels that we have now.

    There are the following related discussions:

    • https://github.com/reactor/reactor-core/issues/979#issuecomment-351770494 describes preliminary performance test that indicates that "push" mode is much faster for same-thread cases.
    • https://github.com/Kotlin/kotlinx.coroutines/issues/113 (SPSC channels) seems to get superseded by the support of cold streams.
    enhancement 
    opened by elizarov 116
  • Introduce SharedFlow

    Introduce SharedFlow

    Introduction

    There is a need to have a Flow implementation that is hot (always active independently of collectors) and shares emitted values among all collectors that subscribe to it. Its design generalizes StateFlow beyond the narrow set of use-case it supports (see #1973). Previously it was discussed in various issues under the tentative name of EventFlow, but having analyzed use-cases and worked out the draft design we believe that SharedFlow better describes what it is. It will replace all sorts of BroadcastChannel implementations and serves as a basis for the design of shareIn operator. The simplest version of sharing operator builds a combination of a SharedFlow that downstream collects from and an upstream flow that emits into this SharedFlow. See #2047 for details on sharing operators.

    Use-cases

    • Synchronous (rendezvous) flow-based event listeners (emit event, suspend until all listeners process it, see #1901).
    • Replay & buffering of last events (important for non-suspend context, buffer cushions fast producers, see #1761).
    • Advanced state sharing (custom conflation, no initial value, etc. see comments in #1973).
    • Get access to “the current cache snapshot” which for non-live display purposes (confirmation dialog window), etc.
    • Custom “upstream” connection logic by tracking the number of active collectors (see discussion in #1086).

    Design overview

    The design has two interfaces SharedFlow/MutableSharedFlow just like SharedState/MutableSharedState:

    interface SharedFlow<out T> : Flow<T> {
        val replayCache: List<T>
    }
    
    interface MutableSharedFlow<T> : SharedFlow<T>, FlowCollector<T> {
        fun tryEmit(value: T): Boolean
        val subscriptionCount: StateFlow<Int>
        fun resetReplayCache()
    }
    
    • SharedFlow is a regular Flow plus:
      • replayCache is a snapshot of the current replay cache for non-reactive use (show dialog, etc).
    • MutableSharedFlow is a FlowCollector (upstream flow can directly emit to it) plus:
      • tryEmit - non suspending variant of emit (for regular non-suspending event listeners, named consistently with upcoming trySend, see #974);
      • subscriptionCount - exposes the current number of subscriptions (active collectors) as a StateFlow, which allows to easily implement any kind of advanced upstream data connection policy if needed;
      • resetReplayCache - resets the replay cache. It is useful for very transient data that should not be replayed to collectors when its upstream is not active.

    Instances of MutableSharedFlow are created with the constructor function:

    fun <T> MutableSharedFlow(
        replay: Int = 0,
        extraBufferCapacity: Int = 0,
        onBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND
    ): MutableSharedFlow<T>
    

    It has the following parameters:

    • replay - how many items are replayed to new subscribers (optional, defaults to zero);
    • extraBufferCapacity - how many items are buffered in addition to replay so that emit does not suspend while there is a buffer remaining (optional, defaults to zero);
    • onBufferOverflow - configures an action on buffer overflow (optional, defaults to suspending emit call, supported only when replay > 0 or extraBufferCapacity > 0).

    Buffer overflow

    The case of the shared flow without buffer (created with MutableSharedFlow()) is special. It is a rendezvous shared flow where each emit call suspends until all collectors process the emitted value. tryEmit call on such a flow never succeeds and always returns false.

    In a case with buffering the call to emit may ether put the value into the buffer and return immediately (tryEmit does the same and returns true in this case) or, if there are slow collectors that have not processed previously buffered values yet, emit call will suspend (tryEmit does nothing and returns false in this case). The action on buffer overflow can be configured with onBufferOverflow parameter, which essentially configures what should be sacrificed on overflow:

    enum class BufferOverflow {
        SUSPEND,     // default behavior
        DROP_OLDEST, // ~ conflate() operator
        DROP_LATEST  // ~ dropWhenBusy() operator
    }
    

    If anything other than the default SUSPEND is configured, then emit never suspends and tryEmit always returns true, handling the buffer overflow by either DROP_OLDEST strategy (drops the oldest value in the buffer, the slow collectors will not see it, makes sure that latest value is kept) or DROP_LATEST strategy (drops the newly emitted value, keeps the old buffered values).

    Example usage in code

    class EventBus {
        private val _events = MutableSharedFlow<Event>() // no buffer, rendezvous with subscribers
        public val events: Flow<Event> get() = _events // expose as a plain flow
        
        suspend fun produceEvent(event: Event) {
            _events.emit(event) // suspends until all subscribers receive it
        }
    }
    

    Error handling

    The big elephant in the room of SharedFlow design is error handling. BroadcastChannel design and similar primitives in Rx propagate errors from upstream to downstream. We could do the same, but propagating errors immensely complicates the design and creates the following problems:

    • Caching and replay design has to take the “upstream error” state into consideration. Does the error state count against the buffer size? If the error is cleared on resetBuffer or is there a separate way to reset the error state? etc...
    • Upstream might encounter error before a single downstream collector appears or after all downstream collectors are canceled. Now, a potentially fatal error report just sits there, cached in SharedFlow for unbounded time, and is not being reported to any kind of error-handling code. This is not good for reliable applications.

    What are the actual use-cases for error handling? What needs to happen when there is an error in the upstream? It looks like the following error handling strategies observed in the wild account for the majority of error-handling use-cases:

    • Retry on errors: This is a popular strategy when upstream flow is retrieving data via unreliable network.
    • Materialize errors: This is a popular strategy in UI applications to make it easier to propagate error via API layers so that they can be presented in the UI.

    Both of the strategies already have existing Flow APIs to retry and to catch errors and they can be used on the upstream flow before emitting events to the SharedFlow. In essence, all kinds of completion and error states can be always materialized as emitted values to share them. This way, sharing design becomes completely decoupled and orthogonal to error handling.

    Note, that sharing operators will always have a CoroutineScope they work in and will benefit from structured concurrency (see discussion #1261). If any error is not caught and reaches a sharing operator this scope gives a natural and consistent point to promptly report all the unhandled errors so that application-wide mechanisms can properly log or otherwise report them.

    SharedFlow never completes

    As a side-effect of this error-handling design decision, the SharedFlow never completes. A call collect { ... } on a SharedFlow must be canceled to terminate it. However, if completion is needed, then it can always be materialized by a special emitted value. A collector can apply takeWhile operator to complete the resulting flow when this special value is encountered.

    Deprecation of BroadcastChannel

    The SharedFlow is designed to completely replace all kinds of BroadcastChannel implementations. They will be supported but will be deprecated as soon as SharedFlow becomes stable:

    • ConflatedBroadcastChannel()MutableStateFlow()
    • BroadcastChannel(capacity)MutableSharedFlow(replay = 0, extraBufferCapacity = capacity)

    MutableSharedFlow is not a drop-in replacement for BroadcastChannel. There are the following major functional differences that have to be addressed during replacement:

    • BroadcastChannel is actually capable of directly representing an error state (and causes the error-handling problem described above, that one this being one of the reasons to deprecate it). So, a code that was relying on this error-handling capability of BroadcastChannel will have to be changed to materialize those errors using catch operator.
    • BroadcastChannel supports various advanced Channel APIs, like select expression. If needed on the downstream side, the resulting SharedFlow can be converted to a channel via produceIn operator, if needed on the upstream side, the channelFlow builder can be used.

    StateFlow is SharedFlow

    Last, but not the least, StateFlow (see #1973) is trivially retrofitted to implement a SharedFlow with MutableStateFlow implementing MutableSharedFlow:

    • replayCache is singleton list of the current value;
    • trivial tryEmit, emit that could be useful for composition (can emit another flow into StateFlow)
    • subscriptionCount could be useful for state flows, too.
    • resetReplayCache is not supported.

    With this change, SharedFlow consistently becomes the only hot flow in the library; easy to see and learn by its type. When something is a SharedFlow it means that it is always live regardless of the presence of collector and all emissions are shared among collectors.

    StateFlow becomes a special-purpose, high-performance, and efficient implementation of SharedFlow for narrow, but widely used case of sharing a state. In fact, a shared flow behaves identically to a state flow when it is created with the following parameters and distinctUntilChanged operator is applied to it:

    // MutableStateFlow(initialValue) is a shared flow with the following parameters:
    val shared = MutableSharedFlow(
        replay = 1,
        onBufferOverflow = BufferOverflow.DROP_OLDEST,
    )
    shared.tryEmit(initialValue) // emit the initial value
    val state = shared.distinctUntilChanged() // get StateFlow-like behavior
    

    The above information will be added to StateFlow documentation, thus giving easily actionable advice on what to do when you have a use-case that is almost like a StateFlow, but with some tweaks (more buffer space, support duplicate emissions, does not have an initial value, etc).

    onSubscription operator

    The following operator that is specific to shared flows is added:

    fun <T> SharedFlow<T>.onSubscription(action: suspend FlowCollector<T>.() -> Unit): SharedFlow<T>
    

    It is similar to onStart with one big difference. onStart calls the action before a subscription to the shared flow is established. It means that if onStart action initiates an operation that emits the values into the shared flow, there is no guarantee that those emissions will be received by this downstream collector. However, onSubscription calls the action after a subscription to the shared flow is established, guaranteeing the reception of all the emitted values after this moment (assuming they are not dropped on buffer overflow).

    sharedFlow.onStart { sharedFlow.emit("x") }.onEach { /* may miss "x" */ }
    sharedFlow.onSubscription { sharedFlow.emit("y") }.onEach { /* guaranteed to collect "x" */ }
    

    Implementation

    Implementation is in PR #2069.

    flow flow-sharing 
    opened by elizarov 79
  • SendChannel.offer should never throw

    SendChannel.offer should never throw

    As of version 1.1.1, if you call offer from the non blocking world (which doesn't handle CancellationException by default, on a closed Channel, an exception is thrown, which by default will crash the program.

    This is a problem in several ways:

    1. offer which returns a Boolean per its signature actually is kind of a "tri-lean" as if the channel is closed, it will not return false but throw.
    2. offer is possibly called from a thread that is not the one where the callback that offers the values is unregistered, so race conditions may imply offer being called once or a few times after the channel is closed, and usually, the intention is to ignore those. Simply returning false instead of throwing would likely be a better behavior.
    3. There's no way to offer without having this function possibly throw, because by the time isClosedForSend returns false, it may have been closed due to concurrent execution, so a subsequent call to offer would throw.

    My current workaround is the following:

    fun <E> SendChannel<E>.offerCatching(element: E): Boolean {
        return runCatching { offer(element) }.getOrDefault(false)
    }
    
    enhancement channels For 1.4 
    opened by LouisCAD 65
  • Change default for global vs child coroutines by scoping coroutine builder (structured concurrency)

    Change default for global vs child coroutines by scoping coroutine builder (structured concurrency)

    Background and definitions

    Currently coroutine builders like launch { ... } and async { ... } start a global coroutine by default. By global we mean that this coroutine's lifetime is completely standalone just like a lifetime of a daemon thread and outlives the lifetime of the job that had started it. It is terminated only explicitly or on shutdown of the VM, so the invoker had to make extra steps (like invoking join/await/cancel) to ensure that it does live indefinitely.

    In order to start a child coroutine a more explicit and lengthly invocation is needed. Something like async(coroutineContext) { ... } and async(coroutineContext) { ... } or async(parent=job) { ... }, etc. Child coroutine is different from a global coroutine in how its lifetime is scoped. The lifetime of child coroutine is strictly subordinate to the lifetime of its parent job (coroutine). A parent job cannot complete until all its children are complete, thus preventing accidental leaks of running children coroutines outside of parent's scope.

    Problem

    This seems to be a wrong default. Global coroutines are error-prone. They are easy to leak and they do not represent a typical use-case where some kind of parallel decomposition of work is needed. It is easy to miss the requirement of adding an explicit coroutineContext or parent=job parameter to start a child coroutine, introducing subtle and hard to debug problems in the code.

    Consider the following code that performs parallel loading of two images and returns a combined result (a typical example of parallel decomposition):

    suspend fun loadAndCombineImage(name1: String, name2: String): Image {
        val image1 = async { loadImage(name1) }
        val image2 = async { loadImage(name2) }
        return combineImages(image1.await(), image2.await())
    }
    

    This code has a subtle bug in that if loading of the first image fails, then the loading of the second one still proceeds and is not cancelled. Moreover, any error that would occur in the loading of the second image in this case would be lost. Note, that changing async to async(coroutineContext) does not fully solve the problem as it binds async loading of images to the scope of the larger (enclosing) coroutine which is wrong in this case. In this case we want these async operations to be children of loadAndCombineImage operation.

    For some additional background reading explaining the problem please see Notes on structured concurrency, or: Go statement considered harmful

    Solution

    The proposed solution is to deprecate top-level async, launch, and other coroutine builders and redefine them as extension functions on CoroutineScope interface instead. A dedicated top-level GlobalScope instance of CoroutineScope is going to be defined.

    Starting a global coroutine would become more explicit and lengthly, like GlobalScope.async { ... } and GlobalScope.launch { ... }, giving an explicit indication to the reader of the code that a global resource was just created and extra care needs to be taken about its potentially unlimited lifetime.

    Starting a child coroutine would become less explicit and less verbose. Just using async { ... } or launch { ... } when CoroutineScope is in scope (pun intended) would do it. In particular, it means that the following slide-ware code would not need to use join anymore:

    fun main(args: Array<String>) = runBlocking { // this: CoroutineScope 
        val jobs = List(100_000) { 
            launch {
                delay(1000)
                print(".")
            }
        }
        // no need to join here, as all launched coroutines are children of runBlocking automatically
    }
    

    For the case of parallel decomposition like loadAndCombineImage we would define a separate builder function to capture and encapsulate the current coroutine scope, so that the following code will work properly in all kind of error condition and will properly cancel the loading of the second image when loading of the first one fails:

    suspend fun loadAndCombineImage(name1: String, name2: String): Image = coroutineScope { // this: CoroutineScope 
        val image1 = async { loadImage(name1) }
        val image2 = async { loadImage(name2) }
        combineImages(image1.await(), image2.await())
    }
    

    Additional goodies

    Another idea behind this design is that it should be easy to turn any entity with life-cycle into an entity that you could start coroutines from. Consider, for example, some kind of an application-specific activity that is launch some coroutines but all of those coroutines should be cancelled when the activity is destroyed (for example). Now it looks like this:

    class MyActivity {
        val job = Job() // create a job as a parent for coroutines
        val backgroundContext = ... // somehow inject some context to launch coroutines
        val ctx = backgroundContext + job // actual context to use with coroutines
    
        fun doSomethingInBackground() = launch(ctx) { ... }
        fun onDestroy() { job.cancel() }    
    }
    

    The proposal is to simply this pattern, by allowing an easy implementation of CoroutineScope interface by any business entities like the above activity:

    class MyActivity : CoroutineScope {
        val job = Job() // create a job as a parent for coroutines
        val backgroundContext = ... // somehow inject some context to launch coroutines
        override val scopeContext = backgroundContext + job // actual context to use with coroutines
    
        fun doSomethingInBackground() = launch { ... } // !!! 
        fun onDestroy() { job.cancel() }    
    }
    

    Now we don't need to remember to specify the proper context when using launch anywhere in the body of MyActivity class and all launched coroutines will get cancelled when lifecycle of MyActivity terminates.

    enhancement design for 1.0 release 
    opened by elizarov 63
  • Flow.share operator

    Flow.share operator

    The share() operator operates on Flow<T> and returns Flow<T>. It shall have the following semantics. The resulting flow is cold, but when one collector shart collecting from it, the it starts to collect from the upstream flow, activating the emitter upstream. The trick of the share operator is that when additional collectors appear in the downstream, they all "share" the same upstream emitter.

    For example, consider the flow:

    val flow = flow { 
        var i = 0
        while(true) { 
            delay(1000) 
            println("Emit $i")
            emit(i++)
        }
    }
    

    If you launch two collectors:

    launch { flow.collect { println("A: got $it") } }
    launch { flow.collect { println("B: got $it") } }
    

    Then you shall see "Emit 0 / A: got 0 / Emit 0 / B: got 0 / Emit 1 / A: got 1 / Emit 1 / B: got 1 / ...".

    However, if you change the flow to val flow = flow { /* same */ }.share(), then you shall see "Emit 0 / A: got 0 / B: got 0 / Emit 1 / A: got 1 / B: got 1 / ...", that is one emission gets delivered to both collectors.

    Now if you need to artificially "start" the shared flow simply to keep it active, then you can always launch a dummy collector: launch { flow.collect {} } that works as a "reference" which is active until you cancel the resulting job.

    TBD: Share operator might need some configuration with the respect to how much "history" to keep in memory for "late collectors". So far it seems that one non-negative integer is enough (with zero -- new collector don't get any history, with one -- only the most recent value, with more -- the specified number of recent values). What is unclear is what shall be the default value (if any).

    UPDATE: It will have to be, actually, a shareIn(scope) operator. Otherwise, the scope it works in will be bound the the first collectors and when this callector is cancelled it will not be able to maintain emissions to other collectors.

    flow flow-sharing 
    opened by elizarov 62
  • Introduce StateFlow

    Introduce StateFlow

    We need to be able to conveniently use Flow to represent an updateable state in applications. This change introduces StateFlow -- an updateable value that represents a state and is a Flow. The design is flexible to fit a variety of needs:

    • StateFlow<T> interface is a read-only view that gives access to the current value and implements a Flow<T> to collect updates to the values.
    • MutabaleStateFlow<T> interface adds value-modification operation.

    A MutableStateFlow(x) constructor function is provided. It returns an implementation of MutableStateFlow with the given initial value. It can be exposed to the outside world as either StateFlow<T> if fast non-reactive access to the value is needed, or as Flow<T> if only reactive view of updates to the value is needed.

    Core state flow API can be summarized like this:

    package kotlinx.coroutines.flow
    
    interface StateFlow<T> : Flow<T> {
        val value: T // always availabe, reading it never fails
    }
    
    interface MutableStateFlow<T> : StateFlow<T> {
        override var value: T // can read & write value
    }
    
    fun <T> MutableStateFlow(value: T): MutableStateFlow<T> // constructor fun
    

    Implementation is available in PR #1974.

    StateFlow vs ConflatedBroadcastChannel

    Conceptually state flow is similar to ConflatedBroadcastChannel and is designed to completely replace ConflatedBroadcastChannel in the future. It has the following important improvements:

    • StateFlow is simpler because it does not have to implement all the Channel APIs, which allows for faster, garbage-free implementation, unlike ConflatedBroadcastChannel implementation that allocates objects on each emitted value.
    • StateFlow always has a value that can be safely read at any time via value property. Unlike ConflatedBroadcastChannel, there is no way to create a state flow without a value.
    • StateFlow has a clear separation into a read-only StateFlow interface and a MutableStateFlow.
    • StateFlow conflation is based on equality, unlike conflation in ConflatedBroadcastChannel that is based on reference identity. It is a stronger, more practical conflation policy, that avoids extra updates when data classes are emitted. You can consider it to have an embedded distinctUntilChanged out-of-the-box.
    • StateFlow cannot be currently closed like ConflatedBroadcastChannel and can never represent a failure. This feature might be added in the future if enough compelling use-cases are found.

    StateFlow is designed to better cover typical use-cases of keeping track of state changes in time, taking more pragmatic design choices for the sake of convenience.

    Example

    For example, the following class encapsulates an integer state and increments its value on each call to inc:

    class CounterModel {
        private val _counter = MutableStateFlow(0) // private mutable state flow
        val counter: StateFlow<Int> get() = _counter // publicly exposed as read-only state flow
    
        fun inc() {
            _counter.value++ // convenient state update
        }
    }
    

    Experimental status

    The initial version of this design is going to be introduced under @ExperimentalCoroutinesApi, but it is highly unlikely that the core of the design as described above, is going to change. It is expected to be stabilized quite fast.

    There are also some future possible enhancements (see below) that are not provided at this moment.

    Possible future enhancement: Closing state flow

    A state flow could be optionally closed in a similar way to channels. When state flow is closed all its collectors complete normally or with the specified exception. Closing a state flow transitions it to the terminal state. Once the state flow is closed its value cannot be changed. The most recent value of the closed state flow is still available via value property. Closing a state is appropriate in situations where the source of the state updates is permanently destroyed.

    To support closing there would be a MutableStateFlow.close(cause: Throwable? = null): Boolean method for the owner of the state flow to close it via its writeable reference and StateFlow.isClosed: Boolean property on read-only interface.

    UPDATE: Turning Flow into a StateFlow

    A regular Flow is cold. It does not have the concept of the last value and it only becomes active when collected. We introduce a stateIn operator to turn any Flow into a hot StateFlow in the as a part of the family of flow-sharing operators (see #2047 ). It is designed to become a replacement for broadcastIn operator. It would subsume the need of having to have a separate "state flow builder" as you can simply write flow { .... }.stateIn(scope) to launch a coroutine that emits the values according to the code in curly braces.

    enhancement flow 
    opened by elizarov 60
  • runBlockingTest fails with

    runBlockingTest fails with "This job has not completed yet"

    This simple block:

      runBlockingTest {
       suspendCancellableCoroutine<Unit> { cont ->
         thread {
           Thread.sleep(1000)
           cont.resume(Unit)
         }
       }
     }
    

    Fails with the exception:

    Exception in thread "main" java.lang.IllegalStateException: This job has not completed yet
        at kotlinx.coroutines.JobSupport.getCompletionExceptionOrNull(JobSupport.kt:1114)
        at kotlinx.coroutines.test.TestBuildersKt.runBlockingTest(TestBuilders.kt:53)
        at kotlinx.coroutines.test.TestBuildersKt.runBlockingTest$default(TestBuilders.kt:45)
        at SamplKt.main(Sampl.kt:8)
        at SamplKt.main(Sampl.kt)
    

    This looks like a bug to me as it should pass.

    Kotlin 1.3.31 Coroutines 1.2.1

    test 
    opened by PaulWoitaschek 58
  • Add Subscribable interfaces

    Add Subscribable interfaces

    Resolve #245

    This PR add the following:

    • interface Subscribable: Represent anything from which it is possible to open a subscription
    • interface SubscribableValue: Represent a Subscriblable from which it is always possible to get a current value.
    • interface SubscriblableVariable: Mutable SubscribableValue allowing to set the current value
    • factory functions SubscribableValue(value)and SubscribableVariable(intialValue): Which create instances for the corresponding interfaces.

    This PR also make BroadcastChannel a sub interface of Subscribable.

    Decisions made:

    • We do not support late initialization. Therefore ConflatedBroadacstChannel do not implement SusbcribableVariable. This makes the overall usage simpler and safer to use.
    • Operators such as map and combine or adapter for JavaFX ObservableValue won't be part of this PR, but may be made and discussed in another issue/PR
    opened by jcornaz 56
  • Consider making BroadcastChannels to implement Flow

    Consider making BroadcastChannels to implement Flow

    Unlike point-to-point channels that are somewhat tricky to use, various kinds of BroadcastChannel implementations seem well suited to directly implement Flow interface. That would make easier and slightly more efficient to use them as "data model" classes in MVVM architectures, being able to directly use full set of flow operators to transform them and wire to UI.

    Also, we might consider a shorter name for ConflatedBroadcastChannel that would focus on its "dataflow variable" nature. DataFlow could be a good starting point for this name bike-shedding.

    design flow 
    opened by elizarov 51
  • Slow android Dispatchers.Main init

    Slow android Dispatchers.Main init

    It seems Android Main dispatcher initialization / discovery can be quite slow currently.

    On a Nokia 8 device my application startup time went from 250ms to 500ms (on release mode). I know that 250ms does not sound much but it's pretty much 2 times slower startup time and it does impact the users as they often want the fastest possible startup time for this kind of application. And I still have to see on older devices if the impact is 250ms or linear with the device power.

    See attached flamechart (It's from the debug app with full trace profiling so the times are insanely slow but was necessary to find the issue).

    coroutine flame chart

    Is there a way to bypass that slow factory discovery and statically create my own Main dispatcher on Android to avoid that slowdown?

    opened by Tolriq 50
  • Introduce first version of Dispatchers.IO for K/N

    Introduce first version of Dispatchers.IO for K/N

    • Emulate expect declaration refinement via extension property as the only way to do it in a backwards-compatible manner: in the current model it is impossible to have common 'expect' Dispatchers declaration, then refined 'concurrent' Dispatchers declaration with 'expect val IO' and then JVM declaration with JVM-specific members. Current solutions seems to be the less intrusive one
    • Elasticity is not supported as K/N Workers API lacks capability to gracefully shutdown workers, meaning that for any unlimited underlying pool, memory consumption is only going to grow in an unbound manner

    Fixes #3205

    opened by qwwdfsad 0
  • Investigate possibilities to extend darwin's Dispatcher.Default with priorities/QOS classes

    Investigate possibilities to extend darwin's Dispatcher.Default with priorities/QOS classes

    For OS X-specific targets, Dispatchers.Default is backed by Darwin's global queue with default priority.

    Yet there exist enough usages of Swift/Obj-C code that leverage priorities other than default (example), raising the question whether we should provide an access to such priorities ourselves.

    The API form is subject to bikeshed (the preliminary idea is to introduce something like Dispatchers.Default.HighPriority), this issue is intended to be an umbrella for use-cases to see if there exists such demand at all

    enhancement use-case needed native 
    opened by qwwdfsad 0
  • Increment WorkQueue.blockingTasksInBuffer only after capacity check

    Increment WorkQueue.blockingTasksInBuffer only after capacity check

    Otherwise, it is possible to leave dangling blockingTasksInBuffer increment that will never be decremented back, leading to unnecessary full-scans on any attempt to steal only blocking task. This change does not have a corresponding unit-test because it fixes the performance regression that is not observable semantically

    opened by qwwdfsad 0
  • Wrong output given in api documentation of runningFold

    Wrong output given in api documentation of runningFold

    There is a minor documentation error in the api docs of runningFold. The output in the example should be a list of lists:

    will produce [], [1], [1, 2], [1, 2, 3] --> will produce [[], [1], [1, 2], [1, 2, 3]]

    docs 
    opened by kfh 1
Releases(1.6.4)
  • 1.6.4(Jul 13, 2022)

    • Added TestScope.backgroundScope for launching coroutines that perform work in the background and need to be cancelled at the end of the test (#3287).
    • Fixed the POM of kotlinx-coroutines-debug having an incorrect reference to kotlinx-coroutines-bom, which cause the builds of Maven projects using the debug module to break (#3334).
    • Fixed the Publisher.await functions in kotlinx-coroutines-reactive not ensuring that the Subscriber methods are invoked serially (#3360). Thank you, @EgorKulbachka!
    • Fixed a memory leak in withTimeout on K/N with the new memory model (#3351).
    • Added the guarantee that all Throwable implementations in the core library are serializable (#3328).
    • Moved the documentation to https://kotlinlang.org/api/kotlinx.coroutines/ (#3342).
    • Various documentation improvements.
    Source code(tar.gz)
    Source code(zip)
  • 1.6.3(Jun 20, 2022)

  • 1.6.2(May 27, 2022)

    • Fixed a bug with ThreadLocalElement not being correctly updated when the most outer suspend function was called directly without kotlinx.coroutines (#2930).
    • Fixed multiple data races: one that might have been affecting runBlocking event loop, and a benign data race in Mutex (#3250, #3251).
    • Obsolete TestCoroutineContext is removed, which fixes the kotlinx-coroutines-test JPMS package being split between kotlinx-coroutines-core and kotlinx-coroutines-test (#3218).
    • Updated the ProGuard rules to further shrink the size of the resulting DEX file with coroutines (#3111, #3263). Thanks, @agrieve!
    • Atomicfu is updated to 0.17.2, which includes a more efficient and robust JS IR transformer (#3255).
    • Kotlin is updated to 1.6.21, Gradle version is updated to 7.4.2 (#3281). Thanks, @wojtek-kalicinski!
    • Various documentation improvements.
    Source code(tar.gz)
    Source code(zip)
  • 1.6.1(Apr 4, 2022)

    • 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.
    Source code(tar.gz)
    Source code(zip)
  • 1.6.0(Dec 22, 2021)

    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.

    kotlinx-coroutines-test rework

    • kotlinx-coroutines-test became a multiplatform library usable from K/JVM, K/JS, and K/N.
    • Its API was completely reworked to address long-standing issues with consistency, structured concurrency and correctness (#1203, #1609, #2379, #1749, #1204, #1390, #1222, #1395, #1881, #1910, #1772, #1626, #1742, #2082, #2102, #2405, #2462 ).
    • The old API is deprecated for removal, but the new API is based on the similar concepts (README), and the migration path is designed to be graceful: migration guide.

    Dispatchers

    • Introduced CoroutineDispatcher.limitedParallelism that allows obtaining a view of the original dispatcher with limited parallelism (#2919).
    • Dispatchers.IO.limitedParallelism usages ignore the bound on the parallelism level of Dispatchers.IO itself to avoid starvation (#2943).
    • Introduced new Dispatchers.shutdown method for containerized environments (#2558).
    • newSingleThreadContext and newFixedThreadPoolContext are promoted to delicate API (#2919).

    Breaking changes

    • When racing with cancellation, the future builder no longer reports unhandled exceptions into the global CoroutineExceptionHandler. Thanks @vadimsemenov! (#2774, #2791).
    • Mutex.onLock is deprecated for removal (#2794).
    • Dispatchers.Main is now used as the default source of time for delay and withTimeout when present (#2972).
      • To opt-out from this behaviour, kotlinx.coroutines.main.delay system property can be set to false.
    • Java target of coroutines build is now 8 instead of 6 (#1589).
    • Source-breaking change: extension collect no longer resolves when used with a non-in-place argument of a functional type. This is a candidate for a fix, uncovered after 1.6.0, see #3107 for the additional details.

    Bug fixes and improvements

    • Kotlin is updated to 1.6.0.
    • Kotlin/Native new memory model is now supported in regular builds of coroutines conditionally depending on whether kotlin.native.binary.memoryModel is enabled (#2914).
    • Introduced CopyableThreadContextElement for mutable context elements shared among multiple coroutines. Thanks @yorickhenning! (#2893).
    • transformWhile, awaitClose, ProducerScope, merge, runningFold, runingReduce, and scan are promoted to stable API (#2971).
    • SharedFlow.subscriptionCount no longer conflates incoming updates and gives all subscribers a chance to observe a short-lived subscription (#2488, #2863, #2871).
    • Flow exception transparency mechanism is improved to be more exception-friendly (#3017, #2860).
    • Cancellation from flat* operators that leverage multiple coroutines is no longer propagated upstream (#2964).
    • SharedFlow.collect now returns Nothing (#2789, #2502).
    • DisposableHandle is now fun interface, and corresponding inline extension is removed (#2790).
    • FlowCollector is now fun interface, and corresponding inline extension is removed (#3047).
    • Deprecation level of all previously deprecated signatures is raised (#3024).
    • The version file is shipped with each JAR as a resource (#2941).
    • Unhandled exceptions on K/N are passed to the standard library function processUnhandledException (#2981).
    • A direct executor is used for Task callbacks in kotlinx-coroutines-play-services (#2990).
    • Metadata of coroutines artifacts leverages Gradle platform to have all versions of dependencies aligned (#2865).
    • Default CoroutineExceptionHandler is loaded eagerly and does not invoke ServiceLoader on its exception-handling path (#2552).
    • Fixed the R8 rules for ServiceLoader optimization (#2880).
    • Fixed BlockHound integration false-positives (#2894, #2866, #2937).
    • Fixed the exception handler being invoked several times on Android, thanks to @1zaman (#3056).
    • SendChannel.trySendBlocking is now available on Kotlin/Native (#3064).
    • The exception recovery mechanism now uses ClassValue when available (#2997).
    • JNA is updated to 5.9.0 to support Apple M1 (#3001).
    • Obsolete method on internal Delay interface is deprecated (#2979).
    • Support of deprecated CommonPool is removed.
    • @ExperimentalTime is no longer needed for methods that use Duration (#3041).
    • JDK 1.6 is no longer required for building the project (#3043).
    • New version of Dokka is used, fixing the memory leak when building the coroutines and providing brand new reference visuals (https://kotlin.github.io/kotlinx.coroutines/) (#3051, #3054).
    Source code(tar.gz)
    Source code(zip)
  • 1.6.0-RC3(Dec 17, 2021)

    • Fixed the error in 1.6.0-RC2 because of which Flow.collect couldn't be called due to the @InternalCoroutinesApi annotation (#3082)
    • Fixed some R8 warnings introduced in 1.6.0-RC (#3090)
    • TestCoroutineScheduler now provides a TimeSource with its virtual time via the timeSource property. Thanks @hfhbd! (#3087)
    Source code(tar.gz)
    Source code(zip)
  • 1.6.0-RC2(Dec 10, 2021)

    • @ExperimentalTime is no longer needed for methods that use Duration (#3041).
    • FlowCollector is now fun interface, and corresponding inline extension is removed (#3047).
    • Fixed the exception handler being invoked several times on Android, thanks to @1zaman (#3056).
    • The deprecated TestCoroutineScope is no longer sealed, to simplify migration from it (#3072).
    • runTest gives more informative errors when it times out waiting for external completion (#3071).
    • SendChannel.trySendBlocking is now available on Kotlin/Native (#3064).
    • Fixed the bug due to which Dispatchers.Main was not used for delay and withTimeout (#3046).
    • JDK 1.6 is no longer required for building the project (#3043).
    • New version of Dokka is used, fixing the memory leak when building the coroutines and providing brand new reference visuals (https://kotlin.github.io/kotlinx.coroutines/) (#3051, #3054).
    Source code(tar.gz)
    Source code(zip)
  • 1.6.0-RC(Nov 22, 2021)

    kotlinx-coroutines-test rework

    • kotlinx-coroutines-test became a multiplatform library usable from K/JVM, K/JS, and K/N.
    • Its API was completely reworked to address long-standing issues with consistency, structured concurrency and correctness (#1203, #1609, #2379, #1749, #1204, #1390, #1222, #1395, #1881, #1910, #1772, #1626, #1742, #2082, #2102, #2405, #2462 ).
    • The old API is deprecated for removal, but the new API is based on the similar concepts (README), and the migration path is designed to be graceful: migration guide

    Dispatchers

    • Introduced CoroutineDispatcher.limitedParallelism that allows obtaining a view of the original dispatcher with limited parallelism (#2919).
    • Dispatchers.IO.limitedParallelism usages ignore the bound on the parallelism level of Dispatchers.IO itself to avoid starvation (#2943).
    • Introduced new Dispatchers.shutdown method for containerized environments (#2558).
    • newSingleThreadContext and newFixedThreadPoolContext are promoted to delicate API (#2919).

    Breaking changes

    • When racing with cancellation, the future builder no longer reports unhandled exceptions into the global CoroutineExceptionHandler. Thanks @vadimsemenov! (#2774, #2791).
    • Mutex.onLock is deprecated for removal (#2794).
    • Dispatchers.Main is now used as the default source of time for delay and withTimeout when present(#2972).
      • To opt-out from this behaviour, kotlinx.coroutines.main.delay system property can be set to false.
    • Java target of coroutines build is now 8 instead of 6 (#1589).

    Bug fixes and improvements

    • Kotlin is updated to 1.6.0.
    • Kotlin/Native new memory model is now supported in regular builds of coroutines conditionally depending on whether kotlin.native.binary.memoryModel is enabled (#2914).
    • Introduced CopyableThreadContextElement for mutable context elements shared among multiple coroutines. Thanks @yorickhenning! (#2839 ).
    • transformWhile, awaitClose, ProducerScope, merge, runningFold, runingReduce, and scan are promoted to stable API (#2971).
    • SharedFlow.subscriptionCount no longer conflates incoming updates and gives all subscribers a chance to observe a short-lived subscription (#2488, #2863, #2871).
    • Flow exception transparency mechanism is improved to be more exception-friendly (#3017, #2860).
    • Cancellation from flat* operators that leverage multiple coroutines is no longer propagated upstream (#2964).
    • SharedFlow.collect now returns Nothing (#2789, #2502).
    • FlowCollector is now fun interface, and corresponding inline extension is removed (#2790).
    • Deprecation level of all previously deprecated signatures is raised (#3024).
    • The version file is shipped with each JAR as a resource (#2941).
    • Unhandled exceptions on K/N are passed to the standard library function processUnhandledException (#2981).
    • A direct executor is used for Task callbacks in kotlinx-coroutines-play-services (#2990).
    • Metadata of coroutines artifacts leverages Gradle platform to have all versions of dependencies aligned (#2865).
    • Default CoroutineExceptionHandler is loaded eagerly and does not invoke ServiceLoader on its exception-handling path (#2552).
    • Fixed the R8 rules for ServiceLoader optimization (#2880).
    • Fixed BlockHound integration false-positives (#2894, #2866, #2937).
    • The exception recovery mechanism now uses ClassValue when available (#2997).
    • JNA is updated to 5.9.0 to support Apple M1 (#3001).
    • Obsolete method on internal Delay interface is deprecated (#2979).
    • Support of deprecated CommonPool is removed.
    Source code(tar.gz)
    Source code(zip)
  • 1.5.2(Sep 2, 2021)

    • Kotlin is updated to 1.5.30.
    • New native targets for Apple Silicon are introduced.
    • Fixed a bug when onUndeliveredElement was incorrectly called on properly received elements on JS (#2826).
    • Fixed Dispatchers.Default on React Native, it now fully relies on setTimeout instead of stub process.nextTick. Thanks to @Legion2 (#2843).
    • Optimizations of Mutex implementation (#2581).
    • Mutex implementation is made completely lock-free as stated (#2590).
    • Various documentation and guides improvements. Thanks to @MasoodFallahpoor and @Pihanya.
    Source code(tar.gz)
    Source code(zip)
  • 1.5.1(Jul 9, 2021)

    • Atomic update, getAndUpdate, and updateAndGet operations of MutableStateFlow (#2720).
    • Executor.asCoroutineDispatcher implementation improvements (#2601):
      • If the target executor is ScheduledExecutorService, then its schedule API is used for time-related coroutine operations.
      • RemoveOnCancelPolicy is now part of the public contract.
    • Introduced overloads for Task.asDeferred and Task.await that accept CancellationTokenSource for bidirectional cancellation (#2527).
    • Reactive streams are updated to 1.0.3 (#2740).
    • CopyableThrowable is allowed to modify the exception message during stacktrace recovery (#1931).
    • CoroutineDispatcher.releaseInterceptedContinuation is now a final method (#2785).
    • Closing a Handler underlying Handler.asCoroutineDispatcher now causes the dispatched coroutines to be canceled on Dispatchers.IO (#2778).
    • Kotlin is updated to 1.5.20.
    • Fixed a spurious ClassCastException in releaseInterceptedContinuation and IllegalStateException from tryReleaseClaimedContinuation (#2736, #2768).
    • Fixed inconsistent exception message during stacktrace recovery for non-suspending channel iterators (#2749).
    • Fixed linear stack usage for CompletableFuture.asDeferred when the target future has a long chain of listeners (#2730).
    • Any exceptions from CoroutineDispatcher.isDispatchNeeded are now considered as fatal and are propagated to the caller (#2733).
    • Internal DebugProbesKt (used in the debugger implementation) are moved from debug to core module.
    Source code(tar.gz)
    Source code(zip)
  • 1.5.0(May 14, 2021)

    Note that this is a full changelog relative to 1.4.3 version. Changelog relative to 1.5.0-RC can be found in the end.

    Channels API

    • Major channels API rework (#330, #974). Existing offer, poll, and sendBlocking methods are deprecated, internal receiveCatching and onReceiveCatching removed, receiveOrNull and onReceiveOrNull are completely deprecated. Previously deprecated SendChannel.isFull declaration is removed. Channel operators deprecated with ERROR are now HIDDEN.
    • New methods receiveCatching, onReceiveCatching trySend, tryReceive, and trySendBlocking along with the new result type ChannelResult are introduced. They provide better type safety, are less error-prone, and have a consistent future-proof naming scheme. The full rationale behind this change can be found here.
    • BroadcastChannel and ConflatedBroadcastChannel are marked as ObsoleteCoroutinesApi in the favor or SharedFlow and StateFlow. The migration scheme can be found in their documentation. These classes will be deprecated in the next major release.
    • callbackFlow and channelFlow are promoted to stable API.

    Reactive integrations

    • All existing API in modules kotlinx-coroutines-rx2, kotlinx-coroutines-rx3, kotlinx-coroutines-reactive, kotlinx-coroutines-reactor, and kotlinx-coroutines-jdk9 were revisited and promoted to stable (#2545).
    • publish is no longer allowed to emit null values (#2646).
    • Misleading awaitSingleOr* functions on Publisher type are deprecated (#2591).
    • MaybeSource.await is deprecated in the favor of awaitSingle, additional lint functions for Mono are added in order to prevent ambiguous Publisher usages (#2628, #1587).
    • ContextView support in kotlinx-coroutines-reactor (#2575).
    • All reactive builders no longer ignore inner cancellation exceptions preventing their completion (#2262, #2646).
    • MaybeSource.collect and Maybe.collect properly finish when they are completed without a value (#2617).
    • All exceptions are now consistently handled according to reactive specification, whether they are considered 'fatal' or not by reactive frameworks (#2646).

    Other improvements

    • Kotlin version is upgraded to 1.5.0 and JVM target is updated to 1.8.
    • Flow.last and Flow.lastOrNull operators (#2246).
    • Flow.runningFold operator (#2641).
    • CoroutinesTimeout rule for JUnit5 (#2197).
    • Internals of Job and AbstractCoroutine was reworked, resulting in smaller code size, less memory footprint, and better performance (#2513, #2512).
    • CancellationException from Kotlin standard library is used for cancellation on Koltin/JS and Kotlin/Native (#2638).
    • Introduced new DelicateCoroutinesApi annotation that warns users about potential target API pitfalls and suggests studying API's documentation first. The only delicate API right now is GlobalScope (#2637).
    • Fixed bug introduced in 1.4.3 when kotlinx-coroutines-core.jar triggered IDEA debugger failure (#2619).
    • Fixed memory leak of ChildHandlerNode with reusable continuations (#2564).
    • Various documentation improvements (#2555, #2589, #2592, #2583, #2437, #2616, #2633, #2560).

    Changelog relative to version 1.5.0-RC

    • Fail-fast during emitAll called from cancelled onCompletion operator (#2700).
    • Flows returned by stateIn/shareIn keep strong reference to sharing job (#2557).
    • Rename internal TimeSource to AbstractTimeSource due to import issues (#2691).
    • Reverted the change that triggered IDEA coroutines debugger crash (#2695, reverted #2291).
    • watchosX64 target support for Kotlin/Native (#2524).
    • Various documentation fixes and improvements.
    Source code(tar.gz)
    Source code(zip)
  • 1.5.0-RC(Apr 26, 2021)

    Channels API

    • Major channels API rework (#330, #974). Existing offer, poll, and sendBlocking methods are deprecated, internal receiveCatching and onReceiveCatching removed, receiveOrNull and onReceiveOrNull are completely deprecated. Previously deprecated SendChannel.isFull declaration is removed. Channel operators deprecated with ERROR are now HIDDEN.
    • New methods receiveCatching, onReceiveCatching trySend, tryReceive, and trySendBlocking along with the new result type ChannelResult are introduced. They provide better type safety, are less error-prone, and have a consistent future-proof naming scheme. The full rationale behind this change can be found here.
    • BroadcastChannel and ConflatedBroadcastChannel are marked as ObsoleteCoroutinesApi in the favor or SharedFlow and StateFlow. The migration scheme can be found in their documentation. These classes will be deprecated in the next major release.
    • callbackFlow and channelFlow are promoted to stable API.

    Reactive integrations

    • All existing API in modules kotlinx-coroutines-rx2, kotlinx-coroutines-rx3, kotlinx-coroutines-reactive, kotlinx-coroutines-reactor, and kotlinx-coroutines-jdk9 were revisited and promoted to stable (#2545).
    • publish is no longer allowed to emit null values (#2646).
    • Misleading awaitSingleOr* functions on Publisher type are deprecated (#2591).
    • MaybeSource.await is deprecated in the favor of awaitSingle, additional lint functions for Mono are added in order to prevent ambiguous Publisher usages (#2628, #1587).
    • ContextView support in kotlinx-coroutines-reactor (#2575).
    • All reactive builders no longer ignore inner cancellation exceptions preventing their completion (#2262, #2646).
    • MaybeSource.collect and Maybe.collect properly finish when they are completed without a value (#2617).
    • All exceptions are now consistently handled according to reactive specification, whether they are considered 'fatal' or not by reactive frameworks (#2646).

    Other improvements

    • Flow.last and Flow.lastOrNull operators (#2246).
    • Flow.runningFold operator (#2641).
    • CoroutinesTimeout rule for JUnit5 (#2197).
    • Internals of Job and AbstractCoroutine was reworked, resulting in smaller code size, less memory footprint, and better performance (#2513, #2512).
    • CancellationException from Kotlin standard library is used for cancellation on Koltin/JS and Kotlin/Native (#2638).
    • Introduced new DelicateCoroutineApi annotation that warns users about potential target API pitfalls and suggests studying API's documentation first. The only delicate API right now is GlobalScope (#2637).
    • Fixed bug introduced in 1.4.3 when kotlinx-coroutines-core.jar triggered IDEA debugger failure (#2619).
    • Fixed memory leak of ChildHandlerNode with reusable continuations (#2564).
    • Various documentation improvements (#2555, #2589, #2592, #2583, #2437, #2616, #2633, #2560).
    Source code(tar.gz)
    Source code(zip)
  • 1.4.3(Mar 3, 2021)

    General changes

    • Thread context is properly preserved and restored for coroutines without ThreadContextElement (#985)
    • ThreadContextElements are now restored in the opposite order from update (#2195)
    • Improved performance of combine with 4 parameters, thanks to @alexvanyo (#2419)
    • Debug agent sanitizer leaves at least one frame with source location (#1437)
    • Update Reactor version in kotlinx-coroutines-reactor to 3.4.1, thanks to @sokomishalov (#2432)
    • callsInPlace contract added to ReceiveChannel.consume (#941)
    • CoroutineStart.UNDISPATCHED promoted to stable API (#1393)
    • Kotlin updated to 1.4.30
    • kotlinx.coroutines are now released directly to MavenCentral
    • Reduced the size of DispatchedCoroutine by a field
    • Internal class TimeSource renamed to SchedulerTimeSource to prevent wildcard import issues (#2537)

    Bug fixes

    • Fixed the problem that prevented implementation via delegation for Job interface (#2423)
    • Fixed incorrect ProGuard rules that allowed shrinking volatile felds (#1564)
    • Fixed await/asDeferred for MinimalStage implementations in jdk8 module (#2456)
    • Fixed bug when onUndeliveredElement wasn't called for unlimited channels (#2435)
    • Fixed a bug when ListenableFuture.isCancelled returned from asListenableFuture could have thrown an exception, thanks to @vadimsemenov (#2421)
    • Coroutine in callbackFlow and produce is properly cancelled when the channel was closed separately (#2506)
    Source code(tar.gz)
    Source code(zip)
  • 1.4.2(Nov 26, 2020)

    • Fixed StackOverflowError in Job.toString when Job is observed in its intermediate state (#2371).
    • Improved liveness and latency of Dispatchers.Default and Dispatchers.IO in low-loaded mode (#2381).
    • Improved performance of consecutive Channel.cancel invocations (#2384).
    • SharingStarted is now fun interface (#2397).
    • Additional lint settings for SharedFlow to catch programmatic errors early (#2376).
    • Fixed bug when mutex and semaphore were not released during cancellation (#2390, thanks to @Tilps for reproducing).
    • Some corner cases in cancellation propagation between coroutines and listenable futures are repaired (#1442, thanks to @vadimsemenov).
    • Fixed unconditional cast to CoroutineStackFrame in exception recovery that triggered failures of instrumented code (#2386).
    • Platform-specific dependencies are removed from kotlinx-coroutines-javafx (#2360).
    Source code(tar.gz)
    Source code(zip)
  • 1.4.1(Nov 3, 2020)

    This is a patch release with an important fix to the SharedFlow implementation.

    • SharedFlow: Fix scenario with concurrent emitters and cancellation of a subscriber (#2359, thanks to @vehovsky for the bug report).
    Source code(tar.gz)
    Source code(zip)
  • 1.4.0(Oct 26, 2020)

    Improvements

    • StateFlow, SharedFlow and corresponding operators are promoted to stable API (#2316).
    • Flow.debounce operator with timeout selector based on each individual element is added (#1216, thanks to @mkano9!).
    • CoroutineContext.job extension property is introduced (#2159).
    • Flow.combine operator is reworked:
      • Complete fairness is maintained for single-threaded dispatchers.
      • Its performance is improved, depending on the use-case, by at least 50% (#2296).
      • Quadratic complexity depending on the number of upstream flows is eliminated (#2296).
      • crossinline and inline-heavy internals are removed, fixing sporadic SIGSEGV on Mediatek Android devices (#1683, #1743).
    • Flow.zip operator performance is improved by 40%.
    • Various API has been promoted to stable or its deprecation level has been raised (#2316).

    Bug fixes

    • Suspendable stateIn operator propagates exception to the caller when upstream fails to produce initial value (#2329).
    • Fix SharedFlow with replay for subscribers working at different speed (#2325).
    • Do not fail debug agent installation when security manager does not provide access to system properties (#2311).
    • Cancelled lazy coroutines are properly cleaned up from debug agent output (#2294).
    • BlockHound false-positives are correctly filtered out (#2302, #2190, #2303).
    • Potential crash during a race between cancellation and upstream in Observable.asFlow is fixed (#2104, #2299, thanks to @LouisCAD and @drinkthestars).
    Source code(tar.gz)
    Source code(zip)
  • 1.4.0-M1(Oct 13, 2020)

    Breaking changes

    • The concept of atomic cancellation in channels is removed. All operations in channels and corresponding Flow operators are cancellable in non-atomic way (#1813).
    • If CoroutineDispatcher throws RejectedExecutionException, cancel current Job and schedule its execution to Dispatchers.IO (#2003).
    • CancellableContinuation.invokeOnCancellation is invoked if the continuation was cancelled while its resume has been dispatched (#1915).
    • Flow.singleOrNull operator is aligned with standard library and does not longer throw IllegalStateException on multiple values (#2289).

    New experimental features

    • SharedFlow primitive for managing hot sources of events with support of various subscription mechanisms, replay logs and buffering (#2034).
    • Flow.shareIn and Flow.stateIn operators to transform cold instances of flow to hot SharedFlow and StateFlow respectively (#2047).

    Other

    • Support leak-free closeable resources transfer via onUndeliveredElement in channels (#1936).
    • Changed ABI in reactive integrations for Java interoperability (#2182).
    • Fixed ProGuard rules for kotlinx-coroutines-core (#2046, #2266).
    • Lint settings were added to Flow to avoid accidental capturing of outer CoroutineScope for cancellation check (#2038).

    External contributions

    • Allow nullable types in Flow.firstOrNull and Flow.singleOrNull by @ansman (#2229).
    • Add Publisher.awaitSingleOrDefault|Null|Else extensions by @sdeleuze (#1993).
    • awaitCancellation top-level function by @LouisCAD (#2213).
    • Significant part of our Gradle build scripts were migrated to .kts by @turansky.

    Thank you for your contributions and participation in the Kotlin community!

    Source code(tar.gz)
    Source code(zip)
  • 1.3.9(Aug 17, 2020)

    • Support of CoroutineContext in Flow.asPublisher and similar reactive builders (#2155).
    • Kotlin updated to 1.4.0.
    • Transition to new HMPP publication scheme for multiplatform usages:
      • Artifacts kotlinx-coroutines-core-common and kotlinx-coroutines-core-native are removed.
      • For multiplatform usages, it's enough to depend directly on kotlinx-coroutines-core in commonMain source-set.
      • The same artifact coordinates can be used to depend on a platform-specific artifact in platform-specific source-set.
    Source code(tar.gz)
    Source code(zip)
  • 1.3.8(Jul 16, 2020)

    New experimental features

    • Added Flow.transformWhile operator (#2065).
    • Replaced scanReduce with runningReduce to be consistent with the Kotlin standard library (#2139).

    Bug fixes and improvements

    • Improve user experience for the upcoming coroutines debugger (#2093, #2118, #2131).
    • Debugger no longer retains strong references to the running coroutines (#2129).
    • Fixed race in Flow.asPublisher (#2109).
    • Fixed ensureActive to work in the empty context case to fix IllegalStateException when using flow from suspend fun main (#2044).
    • Fixed a problem with AbortFlowException in the Flow.first operator to avoid erroneous NoSuchElementException (#2051).
    • Fixed JVM dependency on Android annotations (#2075).
    • Removed keep rules mentioning kotlinx.coroutines.android from core module (#2061 by @mkj-gram).
    • Corrected some docs and examples (#2062, #2071, #2076, #2107, #2098, #2127, #2078, #2135).
    • Improved the docs and guide on flow cancellation (#2043).
    • Updated Gradle version to 6.3 (it only affects multiplatform artifacts in this release).
    Source code(tar.gz)
    Source code(zip)
  • 1.3.7(May 19, 2020)

    • Fixed problem that triggered Android Lint failure (#2004).
    • New Flow.cancellable() operator for cooperative cancellation (#2026).
    • Emissions from flow builder now check cancellation status and are properly cancellable (#2026).
    • New currentCoroutineContext function to use unambiguously in the contexts with CoroutineScope in receiver position (#2026).
    • EXACTLY_ONCE contract support in coroutine builders.
    • Various documentation improvements.
    Source code(tar.gz)
    Source code(zip)
  • 1.3.6(May 8, 2020)

    Flow

    • StateFlow, new primitive for state handling (#1973, #1816, #395). The StateFlow is designed to eventually replace ConflatedBroadcastChannel for state publication scenarios. Please, try it and share your feedback. Note, that Flow-based primitives to publish events will be added later. For events you should continue to either use BroadcastChannel(1), if you put events into the StateFlow, protect them from double-processing with flags.
    • Flow.onEmpty operator is introduced (#1890).
    • Behavioural change in Flow.onCompletion, it is aligned with invokeOnCompletion now and passes CancellationException to its cause parameter (#1693).
    • A lot of Flow operators have left its experimental status and are promoted to stable API.

    Other

    • runInterruptible primitive to tie cancellation with thread interruption for blocking calls. Contributed by @jxdabc (#1947).
    • Integration module with RxJava3 is introduced. Contributed by @ZacSweers (#1883)
    • Integration with BlockHound in kotlinx-coroutines-debug module (#1821, #1060).
    • Memory leak in ArrayBroadcastChannel is fixed (#1885).
    • Behavioural change in suspendCancellableCoroutine, cancellation is established before invoking passed block argument (#1671).
    • Debug agent internals are moved into kotlinx-coroutines-core for better integration with IDEA. It should not affect library users and all the redundant code should be properly eliminated with R8.
    • ClassCastException with reusable continuations bug is fixed (#1966).
    • More precise scheduler detection for Executor.asCoroutineDispatcher (#1992).
    • Kotlin updated to 1.3.71.
    Source code(tar.gz)
    Source code(zip)
  • 1.3.5(Mar 17, 2020)

    Version 1.3.5

    • firstOrNull operators. Contributed by @bradynpoulsen
    • java.time adapters for Flow operators. Contributed by @fvasco
    • kotlin.time.Duration support (#1402). Contributed by @fvasco
    • Memory leak with a mix of reusable and non-reusable continuations is fixed (#1855)
    • DebugProbes are ready for production installation: its performance is increased, the flag to disable creation stacktraces to reduce the footprint is introduced (#1379, #1372)
    • Stacktrace recovery workaround for Android 6.0 and earlier bug (#1866).
    • New integration module: kotlinx-coroutines-jdk9 with adapters for java.util.concurrent.Flow
    • BroadcastChannel.close properly starts lazy coroutine (#1713).
    • kotlinx-coroutines-bom is published without Gradle metadata.
    • Make calls to service loader in reactor integrations optimizable by R8 (#1817)
    Source code(tar.gz)
    Source code(zip)
  • 1.3.4(Mar 6, 2020)

    Flow

    • Detect missing awaitClose calls in callbackFlow to make it less error-prone when used with callbacks (#1762, #1770). This change makes callbackFlow different from channelFlow
    • ReceiveChannel.asFlow extension is introduced (#1490)
    • Enforce exception transparency invariant in flow builder (#1657)
    • Proper Dispatcher support in Flow reactive integrations (#1765)
    • Batch Subscription.request calls in Flow reactive integration (#766)
    • ObservableValue.asFlow added to JavaFx integration module (#1695)
    • ObservableSource.asFlow added to RxJava2 integration module (#1768)

    Other changes

    • kotlinx-coroutines-core is optimized for R8, making it much smaller for Android usages (75 KB for 1.3.4 release)
    • Performance of Dispatchers.Default is improved (#1704, #1706)
    • Kotlin is updated to 1.3.70
    • CoroutineDispatcher and ExecutorCoroutineDispatcher experimental coroutine context keys are introduced (#1805)
    • Performance of various Channel operations is improved (#1565)
    Source code(tar.gz)
    Source code(zip)
  • 1.3.3(Dec 13, 2019)

    Flow

    • Flow.take performance is significantly improved (#1538).
    • Flow.merge operator (#1491).
    • Reactive Flow adapters are promoted to stable API (#1549).
    • Reusable cancellable continuations were introduced that improved the performance of various flow operators and iteration over channels (#1534).
    • Fixed interaction of multiple flows with take operator (#1610).
    • Throw NoSuchElementException instead of UnsupportedOperationException for empty Flow in reduce operator (#1659).
    • onCompletion now rethrows downstream exceptions on emit attempt (#1654).
    • Allow non-emitting withContext from flow builder (#1616).

    Debugging

    • DebugProbes.dumpCoroutines is optimized to be able to print the 6-digit number of coroutines (#1535).
    • Properly capture unstarted lazy coroutines in debugger (#1544).
    • Capture coroutines launched from within a test constructor with CoroutinesTimeout test rule (#1542).
    • Stacktraces of Job-related coroutine machinery are shortened and prettified (#1574).
    • Stacktrace recovery unification that should provide a consistent experience recover of stacktrace (#1597).
    • Stacktrace recovery for withTimeout is supported (#1625).
    • Do not recover exception with a single String parameter constructor that is not a message (#1631).

    Other features

    • Dispatchers.Default and Dispatchers.IO rework: CPU consumption is significantly lower, predictable idle threads termination (#840, #1046, #1286).
    • Avoid ServiceLoader for loading Dispatchers.Main (#1572, #1557, #878, #1606).
    • Consistently handle undeliverable exceptions in RxJava and Reactor integrations (#252, #1614).
    • yield support in immediate dispatchers (#1474).
    • CompletableDeferred.completeWith(result: Result<T>) is introduced.
    • Added support for tvOS and watchOS-based Native targets (#1596).

    Bug fixes and improvements

    • Kotlin version is updated to 1.3.61.
    • CoroutineDispatcher.isDispatchNeeded is promoted to stable API (#1014).
    • Livelock and stackoverflows in mutual select expressions are fixed (#1411, #504).
    • Properly handle null values in ListenableFuture integration (#1510).
    • Making ReceiveChannel.cancel linearizability-friendly.
    • Linearizability of Channel.close in a complex contended cases (#1419).
    • ArrayChannel.isBufferEmpty atomicity is fixed (#1526).
    • Various documentation improvements.
    • Reduced bytecode size of kotlinx-coroutines-core, reduced size of minified dex when using basic functionality of kotlinx-coroutines.
    Source code(tar.gz)
    Source code(zip)
  • 1.3.2(Sep 25, 2019)

    This is a maintenance release that does not include any new features or bug fixes.

    • Reactive integrations for Flow are promoted to stable API.
    • Obsolete reactive API is deprecated.
    • Deprecation level for API deprecated in 1.3.0 is increased.
    • Various documentation improvements.
    Source code(tar.gz)
    Source code(zip)
  • 1.3.1(Sep 4, 2019)

    This is a minor update with various fixes:

    • Flow: Fix recursion in combineTransform<T1, T2, R> (#1466).
    • Fixed race in the Semaphore (#1477).
    • Repaired some of ListenableFuture.kt's cancellation corner cases (#1441).
    • Consistently unwrap exception in slow path of CompletionStage.asDeferred (#1479).
    • Various fixes in documentation (#1496, #1476, #1470, #1468).
    • Various cleanups and additions in tests.

    Note: Kotlin/Native artifacts are now published with Gradle metadata format version 1.0, so you will need Gradle version 5.3 or later to use this version of kotlinx.coroutines in your Kotlin/Native project.

    Source code(tar.gz)
    Source code(zip)
  • 1.3.0(Aug 23, 2019)

    Flow

    This version is the first stable release of Flow API.

    All Flow API not marked with @FlowPreview or @ExperimentalCoroutinesApi annotations are stable and here to stay. Flow declarations marked with @ExperimentalCoroutinesApi have the same guarantees as regular experimental API. Please note that API marked with @FlowPreview have weak guarantees on source, binary and semantic compatibility.

    Changelog

    • A new guide section about Flow.
    • CoroutineDispatcher.asExecutor extension (#1450).
    • Fixed bug when select statement could report the same exception twice (#1433).
    • Fixed context preservation in flatMapMerge in a case when collected values were immediately emitted to another flow (#1440).
    • Reactive Flow integrations enclosing files are renamed for better interoperability with Java.
    • Default buffer size in all Flow operators is increased to 64.
    • Kotlin updated to 1.3.50.
    Source code(tar.gz)
    Source code(zip)
  • 1.3.0-rc2(Aug 9, 2019)

    Flow improvements

    • Operators for UI programming are reworked for the sake of consistency, naming scheme for operator overloads is introduced:

      • combineLatest is deprecated in the favor of combine.
      • combineTransform operator for non-trivial transformations (#1224).
      • Top-level combine and combineTransform overloads for multiple flows (#1262).
      • switchMap is deprecated. flatMapLatest, mapLatest and transformLatest are introduced instead (#1335).
      • collectLatest terminal operator (#1269).
    • Improved cancellation support in flattenMerge (#1392).

    • channelFlow cancellation does not leak to the parent (#1334).

    • Fixed flow invariant enforcement for suspend fun main (#1421).

    • delayEach and delayFlow are deprecated (#1429).

    General changes

    • Integration with Reactor context

      • Propagation of the coroutine context of await calls into Mono/Flux builder.
      • Publisher.asFlow propagates coroutine context from collect call to the Publisher.
      • New Flow.asFlux builder.
    • ServiceLoader-code is adjusted to avoid I/O on the Main thread on newer (3.6.0+) Android toolchain.

    • Stacktrace recovery support for minified builds on Android (#1416).

    • Guava version in kotlinx-coroutines-guava updated to 28.0.

    • setTimeout-based JS dispatcher for platforms where process is unavailable (#1404).

    • Native, JS and common modules are added to kotlinx-coroutines-bom.

    • Fixed bug with ignored acquiredPermits in Semaphore (#1423).

    Source code(tar.gz)
    Source code(zip)
  • 1.3.0-rc(Jul 19, 2019)

    Flow

    • Core Flow API is promoted to stable
    • New basic Flow operators: withIndex, collectIndexed, distinctUntilChanged overload
    • New core Flow operators: onStart and onCompletion
    • ReceiveChannel.consumeAsFlow and emitAll (#1340)

    General changes

    • Kotlin updated to 1.3.41
    • Added kotlinx-coroutines-bom with Maven Bill of Materials (#1110)
    • Reactive integrations are seriously improved
      • All builders now are top-level functions instead of extensions on CoroutineScope and prohibit Job instance in their context to simplify lifecycle management
      • Fatal exceptions are handled consistently (#1297)
      • Integration with Reactor Context added (#284)
    • Stacktrace recovery for suspend fun main (#1328)
    • CoroutineScope.cancel extension with message (#1338)
    • Protection against non-monotonic clocks in delay (#1312)
    • Duration.ZERO is handled properly in JDK 8 extensions (#1349)
    • Library code is adjusted to be more minification-friendly
    Source code(tar.gz)
    Source code(zip)
  • 1.3.0-M2(Jun 26, 2019)

    • Kotlin updated to 1.3.40.
    • Flow exception transparency concept.
    • New declarative Flow operators: onCompletion, catch, retryWhen, launchIn. onError* operators are deprecated in favour of catch. (#1263)
    • Publisher.asFlow is integrated with buffer operator.
    • Publisher.openSubscription default request size is 1 instead of 0 (#1267).
    Source code(tar.gz)
    Source code(zip)
Owner
Kotlin
Kotlin Tools and Libraries
Kotlin
A Kotlin Android library for content provider queries with reactive streams and coroutines.

Pickpocket An Android library for content provider queries with reactive streams and coroutines. Calendar Contacts SMS MMS Files/Media Call Log Bookma

Chris Basinger 27 Nov 14, 2022
Android Library for requesting Permissions with Kotlin Coroutines or AndroidX LiveData

PEKO PErmissions with KOtlin Android Permissions with Kotlin Coroutines or LiveData No more callbacks, builders, listeners or verbose code for request

Marko Devcic 133 Dec 14, 2022
Library to use Kotlin Coroutines from Swift code in KMP apps

KMP-NativeCoroutines A library to use Kotlin Coroutines from Swift code in KMP apps. Flows Kotlin Create an extension property to expose the Flow as a

Rick Clephas 508 Jan 3, 2023
Server Sent Events (SSE) client multiplatform library made with Kotlin and backed by coroutines

OkSSE OkSSE is an client for Server Sent events protocol written in Kotlin Multiplatform. The implementation is written according to W3C Recommendatio

BioWink GmbH 39 Nov 4, 2022
A tiny Kotlin multiplatform library that assists in saving and restoring objects to and from disk using kotlinx.coroutines, kotlinx.serialisation and okio

Store A tiny Kotlin multiplatform library that assists in saving and restoring objects to and from disk using kotlinx.coroutines, kotlinx.serialisatio

Isuru Rajapakse 98 Jan 3, 2023
Opinionated Redux-like implementation backed by Kotlin Coroutines and Kotlin Multiplatform Mobile

CoRed CoRed is Redux-like implementation that maintains the benefits of Redux's core idea without the boilerplate. No more action types, action creato

Kittinun Vantasin 28 Dec 10, 2022
A Kotlin work manager library for Android with progress notifications and Hilt support.

Boot Laces A kotlin work manager library for Android that includes notifications and Hilt support. User Instructions Add the JitPack repository to you

Chris Basinger 35 Oct 8, 2022
Dependency Injection library for Kotlin Multiplatform, support iOS and Android

Multiplatform-DI library for Kotlin Multiplatform Lightweight dependency injection framework for Kotlin Multiplatform application Dependency injection

Anna Zharkova 32 Nov 10, 2022
Android To-Do MVVM Architecture App written in Kotlin.(ViewModel, ROOM, Livedata, Coroutines)

MVVM-To-Do-App A To-Do application written in kotlin using Android Architectural components What's new? Room + Coroutines - Upgraded Room to v2.1. Roo

Naveen T P 77 Dec 8, 2022
async/await for Android built upon coroutines introduced in Kotlin 1.1

Async/Await A Kotlin library for Android to write asynchronous code in a simpler and more reliable way using async/await approach, like: async { pr

MetaLab 411 Dec 22, 2022
Image loading for Android backed by Kotlin Coroutines.

An image loading library for Android backed by Kotlin Coroutines. Coil is: Fast: Coil performs a number of optimizations including memory and disk cac

Coil 8.8k Jan 7, 2023
Android News Reader app. Kotlin Coroutines, Retrofit and Realm

News Reader Android News Reader app Code that follows Packt Publishing Kotlin in Practice Video Course Example of Kotlin Coroutine usage, with Realm a

Marko Devcic 22 Oct 3, 2022
A framework for writing composable parsers based on Kotlin Coroutines.

Parsus A framework for writing composable parsers based on Kotlin Coroutines. val booleanGrammar = object : Grammar<BooleanExpression>() { val ws

Aleksei Semin 28 Nov 1, 2022
Extension functions over Android's callback-based APIs which allows writing them in a sequential way within coroutines or observe multiple callbacks through kotlin flow.

callback-ktx A lightweight Android library that wraps Android's callback-based APIs into suspending extension functions which allow writing them in a

Sagar Viradiya 171 Oct 31, 2022
RSocket, WebFlux, Reactor, Kotlin, Coroutines

RSocket messaging services communication RSocket, WebFlux, Reactor, Kotlin, Coroutines edge-service <-~-> web-service <-~-> coroutines-service <-~-> r

Maksim Kostromin 2 Nov 12, 2021
A Kotlin coroutines wrapper for IndexedDB.

Kotlin IndexedDB A wrapper around IndexedDB which allows for access from Kotlin/JS code using suspend blocks and linear, non-callback based control fl

JUUL Labs 10 Dec 11, 2022
Small lib for recovering stack trace in exceptions thrown in Kotlin coroutines

Stacktrace-decoroutinator Library for recovering stack trace in exceptions thrown in Kotlin coroutines. Supports JVM(not Android) versions 1.8 or high

null 104 Dec 24, 2022
Learning Playground - Kotlin Coroutines

Coroutines Kotlin Playground Coroutines Learning Playground Colaborator Very ope

Faisal Amir 2 Mar 12, 2022
FaceTimeClone app that implements Coroutines , mvvm architecture , clean architecture , navigation component , hilt , etc.... using kotlin language

This repository contains a FaceTimeClone app that implements Coroutines , mvvm architecture , clean architecture , navigation component , hilt , etc.... using kotlin language

null 17 Dec 13, 2022