### Complete example of switching over deferred values Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/select-expression.md A full runnable example demonstrating how to send multiple deferred tasks to a channel and process only the most recent ones. ```kotlin import kotlinx.coroutines.* import kotlinx.coroutines.channels.* import kotlinx.coroutines.selects.* fun CoroutineScope.switchMapDeferreds(input: ReceiveChannel>) = produce { var current = input.receive() // start with first received deferred value while (isActive) { // loop while not cancelled/closed val next = select?> { // return next deferred value from this select or null input.onReceiveCatching { update -> update.getOrNull() } current.onAwait { value -> send(value) // send value that current deferred has produced input.receiveCatching().getOrNull() // and use the next deferred from the input channel } } if (next == null) { println("Channel was closed") break // out of loop } else { current = next } } } fun CoroutineScope.asyncString(str: String, time: Long) = async { delay(time) str } fun main() = runBlocking { //sampleStart val chan = Channel>() // the channel for test launch { // launch printing coroutine for (s in switchMapDeferreds(chan)) println(s) // print each received string } chan.send(asyncString("BEGIN", 100)) delay(200) // enough time for "BEGIN" to be produced chan.send(asyncString("Slow", 500)) delay(100) // not enough time to produce slow chan.send(asyncString("Replace", 100)) delay(500) // give it time before the last one chan.send(asyncString("END", 500)) delay(1000) // give it time to process chan.close() // close the channel ... delay(500) // and wait some time to let it finish //sampleEnd } ``` -------------------------------- ### Complete CoroutineScope Lifecycle Example Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutine-context-and-dispatchers.md A full runnable example demonstrating the creation, usage, and cancellation of a CoroutineScope to manage multiple child coroutines. ```kotlin import kotlinx.coroutines.* class Activity { private val mainScope = CoroutineScope(Dispatchers.Default) // use Default for test purposes fun destroy() { mainScope.cancel() } fun doSomething() { // launch ten coroutines for a demo, each working for a different time repeat(10) { i -> mainScope.launch { delay((i + 1) * 200L) // variable delay 200ms, 400ms, ... etc println("Coroutine $i is done") } } } } // class Activity ends fun main() = runBlocking { //sampleStart val activity = Activity() activity.doSomething() // run test function println("Launched coroutines") delay(500L) // delay for half a second println("Destroying activity!") activity.destroy() // cancels all coroutines delay(1000) // visually confirm that they don't work //sampleEnd } ``` -------------------------------- ### Output of Lazily Started Async Example Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/composing-suspending-functions.md Expected console output showing the result of the computation and the total execution time. ```text The answer is 42 Completed in 1017 ms ``` -------------------------------- ### JavaFX UI Setup Function Placeholder Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md This function is used in JavaFX examples to set up UI elements, receiving references to a Text element and a Circle element. It serves as a placeholder for various UI-related coroutine logic. ```kotlin fun setup(hello: Text, fab: Circle) { // placeholder } ``` -------------------------------- ### Kotlin Full Example of Select with FizzBuzz Producers Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/select-expression.md This complete example demonstrates how to set up and run `fizz` and `buzz` producers, then repeatedly use the `selectFizzBuzz` function to process messages from them, showcasing the `select` expression's behavior. ```kotlin import kotlinx.coroutines.* import kotlinx.coroutines.channels.* import kotlinx.coroutines.selects.* fun CoroutineScope.fizz() = produce { while (true) { // sends "Fizz" every 500 ms delay(500) send("Fizz") } } fun CoroutineScope.buzz() = produce { while (true) { // sends "Buzz!" every 1000 ms delay(1000) send("Buzz!") } } suspend fun selectFizzBuzz(fizz: ReceiveChannel, buzz: ReceiveChannel) { select { // means that this select expression does not produce any result fizz.onReceive { value -> // this is the first select clause println("fizz -> '$value'") } buzz.onReceive { value -> // this is the second select clause println("buzz -> '$value'") } } } fun main() = runBlocking { //sampleStart val fizz = fizz() val buzz = buzz() repeat(7) { selectFizzBuzz(fizz, buzz) } coroutineContext.cancelChildren() // cancel fizz & buzz coroutines //sampleEnd } ``` -------------------------------- ### Launch a basic coroutine Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-basics.md Demonstrates starting a coroutine within a withContext block using the launch builder. ```kotlin suspend fun main() { withContext(Dispatchers.Default) { // this: CoroutineScope // Starts a coroutine inside the scope with CoroutineScope.launch() this.launch { greet() } println("The withContext() on the thread: ${Thread.currentThread().name}") } } ``` -------------------------------- ### Hello World Coroutine Example Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/README.md This example shows a basic `suspend fun main` using `coroutineScope` to launch a new coroutine with `launch`. It demonstrates non-blocking execution where "Hello" is printed before the delayed "Kotlin Coroutines World!". ```kotlin suspend fun main() = coroutineScope { launch { delay(1.seconds) println("Kotlin Coroutines World!") } println("Hello") } ``` -------------------------------- ### Full example of selectAorB function usage in Kotlin Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/select-expression.md This complete example demonstrates how to use the `selectAorB` function with two `produce` channels, printing the results and illustrating `select`'s behavior, including its bias and handling of closed channels. ```kotlin import kotlinx.coroutines.* import kotlinx.coroutines.channels.* import kotlinx.coroutines.selects.* suspend fun selectAorB(a: ReceiveChannel, b: ReceiveChannel): String = select { a.onReceiveCatching { it -> val value = it.getOrNull() if (value != null) { "a -> '$value'" } else { "Channel 'a' is closed" } } b.onReceiveCatching { it -> val value = it.getOrNull() if (value != null) { "b -> '$value'" } else { "Channel 'b' is closed" } } } fun main() = runBlocking { //sampleStart val a = produce { repeat(4) { send("Hello $it") } } val b = produce { repeat(4) { send("World $it") } } repeat(8) { // print first eight results println(selectAorB(a, b)) } coroutineContext.cancelChildren() //sampleEnd } ``` -------------------------------- ### Define Placeholder Setup Function (Android) Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md Initial placeholder function for setting up UI interactions in an Android `MainActivity.kt`. This function will be populated with coroutine logic later. ```kotlin fun setup(hello: TextView, fab: FloatingActionButton) { // placeholder } ``` -------------------------------- ### Execute Async-style Functions and Await Results in Main Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/composing-suspending-functions.md This example demonstrates how to call `xxxAsync` functions from a non-coroutine context and block the main thread using `runBlocking` to await their results. It highlights the need for explicit blocking or suspending to get results from `Deferred` values. ```kotlin import kotlinx.coroutines.* import kotlin.system.* //sampleStart // note that we don't have `runBlocking` to the right of `main` in this example fun main() { val time = measureTimeMillis { // we can initiate async actions outside of a coroutine val one = somethingUsefulOneAsync() val two = somethingUsefulTwoAsync() // but waiting for a result must involve either suspending or blocking. // here we use `runBlocking { ... }` to block the main thread while waiting for the result runBlocking { println("The answer is ${one.await() + two.await()}") } } println("Completed in $time ms") } //sampleEnd @OptIn(DelicateCoroutinesApi::class) fun somethingUsefulOneAsync() = GlobalScope.async { doSomethingUsefulOne() } @OptIn(DelicateCoroutinesApi::class) fun somethingUsefulTwoAsync() = GlobalScope.async { doSomethingUsefulTwo() } suspend fun doSomethingUsefulOne(): Int { delay(1000L) // pretend we are doing something useful here return 13 } suspend fun doSomethingUsefulTwo(): Int { delay(1000L) // pretend we are doing something useful here, too return 29 } ``` -------------------------------- ### Kotlin Coroutines Select onSend Example with Slow Consumer Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/select-expression.md This example demonstrates a producer using 'select' with 'onSend' to manage backpressure by sending to a side channel if the primary consumer is slow. It includes a fast side channel consumer and a slow primary consumer. ```kotlin import kotlinx.coroutines.* import kotlinx.coroutines.channels.* import kotlinx.coroutines.selects.* fun CoroutineScope.produceNumbers(side: SendChannel) = produce { for (num in 1..10) { // produce 10 numbers from 1 to 10 delay(100) // every 100 ms select { onSend(num) {} // Send to the primary channel side.onSend(num) {} // or to the side channel } } } fun main() = runBlocking { //sampleStart val side = Channel() // allocate side channel launch { // this is a very fast consumer for the side channel side.consumeEach { println("Side channel has $it") } } produceNumbers(side).consumeEach { println("Consuming $it") delay(250) // let us digest the consumed number properly, do not hurry } println("Done consuming") coroutineContext.cancelChildren() //sampleEnd } ``` -------------------------------- ### Expected output for deferred switchMap example Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/select-expression.md The console output showing which strings were successfully processed before being replaced or the channel closing. ```text BEGIN Replace END Channel was closed ``` -------------------------------- ### Build and run JVM benchmarks with Gradle and JMH Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/benchmarks/README.md Build the JVM benchmark JAR and execute it with JMH. Requires Gradle and Java installed. ```bash ./gradlew :kotlinx-coroutines-core:jvmBenchmarkBenchmarkJar java -jar kotlinx-coroutines-core/build/benchmarks/jvmBenchmark/jars/kotlinx-coroutines-core-jvmBenchmark-jmh-*-JMH.jar ``` -------------------------------- ### Complete prime number pipeline implementation Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/channels.md Full runnable example that prints the first ten prime numbers and cleans up child coroutines. ```kotlin import kotlinx.coroutines.* import kotlinx.coroutines.channels.* fun main() = runBlocking { //sampleStart var cur = numbersFrom(2) repeat(10) { val prime = cur.receive() println(prime) cur = filter(cur, prime) } coroutineContext.cancelChildren() // cancel all children to let main finish //sampleEnd } fun CoroutineScope.numbersFrom(start: Int) = produce { var x = start while (true) send(x++) // infinite stream of integers from start } fun CoroutineScope.filter(numbers: ReceiveChannel, prime: Int) = produce { for (x in numbers) if (x % prime != 0) send(x) } ``` -------------------------------- ### Implement Lazily Started Async Coroutines Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/composing-suspending-functions.md Use CoroutineStart.LAZY to delay execution until start() or await() is called. Explicitly calling start() before await() ensures concurrent execution. ```kotlin import kotlinx.coroutines.* import kotlin.system.* fun main() = runBlocking { //sampleStart val time = measureTimeMillis { val one = async(start = CoroutineStart.LAZY) { doSomethingUsefulOne() } val two = async(start = CoroutineStart.LAZY) { doSomethingUsefulTwo() } // some computation one.start() // start the first one two.start() // start the second one println("The answer is ${one.await() + two.await()}") } println("Completed in $time ms") //sampleEnd } suspend fun doSomethingUsefulOne(): Int { delay(1000L) // pretend we are doing something useful here return 13 } suspend fun doSomethingUsefulTwo(): Int { delay(1000L) // pretend we are doing something useful here, too return 29 } ``` -------------------------------- ### Expected Output for ThreadLocal asContextElement Example Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutine-context-and-dispatchers.md This output shows the console log from the `ThreadLocal.asContextElement` example, illustrating how the thread-local value is managed and restored across different threads during coroutine execution. ```text Pre-main, current thread: Thread[main @coroutine#1,5,main], thread local value: 'main' Launch start, current thread: Thread[DefaultDispatcher-worker-1 @coroutine#2,5,main], thread local value: 'launch' After yield, current thread: Thread[DefaultDispatcher-worker-2 @coroutine#2,5,main], thread local value: 'launch' Post-main, current thread: Thread[main @coroutine#1,5,main], thread local value: 'main' ``` -------------------------------- ### UI Setup with Coroutines and Animation Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md Launch a coroutine on the main dispatcher to update UI text periodically while handling click events that trigger background computations. Uses GlobalScope.launch with Dispatchers.Main and delay for animation. ```kotlin fun setup(hello: Text, fab: Circle) { var result = "none" // the last result // counting animation GlobalScope.launch(Dispatchers.Main) { var counter = 0 while (true) { hello.text = "${++counter}: $result" delay(100) // update the text every 100ms } } // compute next fibonacci number of each click var x = 1 fab.onClick { result = "fib($x) = ${fib(x)}" x++ } } ``` -------------------------------- ### Alternative Job cancellation setup syntax Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-and-channels.md Shows an alternative way to set up cancellation by explicitly storing the Job result before calling the extension function, equivalent to chaining the extension call directly on launch. ```kotlin val job = launch { } job.setUpCancellation() ``` -------------------------------- ### Start a coroutine with launch Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-and-channels.md Use launch to wrap suspendable logic. This allows the thread to be released during long-running operations like network calls. ```kotlin launch { val users = loadContributorsSuspend(req) updateResults(users, startTime) } ``` -------------------------------- ### Kotlin Coroutines Fan-out Example with Producer and Processors Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/channels.md Demonstrates a complete fan-out scenario where a single producer feeds multiple processor coroutines. The producer is cancelled after a delay, terminating all consumers. ```kotlin import kotlinx.coroutines.* import kotlinx.coroutines.channels.* fun main() = runBlocking { //sampleStart val producer = produceNumbers() repeat(5) { launchProcessor(it, producer) } delay(950) producer.cancel() // cancel producer coroutine and thus kill them all //sampleEnd } fun CoroutineScope.produceNumbers() = produce { var x = 1 // start from 1 while (true) { send(x++) // produce next delay(100) // wait 0.1s } } fun CoroutineScope.launchProcessor(id: Int, channel: ReceiveChannel) = launch { for (msg in channel) { println("Processor #$id received $msg") } } ``` -------------------------------- ### Run background tasks with CoroutineScope.launch() Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-basics.md Starts a new coroutine without blocking the current scope. Returns a Job handle for lifecycle management. ```kotlin // Imports the kotlin.time.Duration to enable expressing duration in milliseconds import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.* suspend fun main() { withContext(Dispatchers.Default) { performBackgroundWork() } } //sampleStart suspend fun performBackgroundWork() = coroutineScope { // this: CoroutineScope // Starts a coroutine that runs without blocking the scope this.launch { // Suspends to simulate background work delay(100.milliseconds) println("Sending notification in background") } // Main coroutine continues while a previous one suspends println("Scope continues") } //sampleEnd ``` -------------------------------- ### Coroutine Builders - mono Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/reactive/kotlinx-coroutines-reactor/README.md Creates a cold Mono that starts the coroutine on subscription. Returns a Mono instance within a CoroutineScope. ```APIDOC ## mono ### Description A cold Mono that starts the coroutine on subscription. ### Result Type `Mono` ### Scope `CoroutineScope` ### Usage Use this builder to create a Mono from a coroutine block. The coroutine will only start executing when the Mono is subscribed to. ``` -------------------------------- ### Launching Nested Coroutines within runBlocking Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-and-channels.md This example demonstrates how `runBlocking` provides a `CoroutineScope` for launching child coroutines, showing both implicit and explicit calls to `launch`. ```kotlin import kotlinx.coroutines.* fun main() = runBlocking { /* this: CoroutineScope */ launch { /* ... */ } // the same as: this.launch { /* ... */ } } ``` -------------------------------- ### Setup UI with Blocking Fibonacci and Animation (Kotlin) Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md This snippet initializes a UI with a continuous counter animation and an event handler that performs a blocking Fibonacci calculation on click. It demonstrates how blocking operations on the main UI thread cause freezes. ```kotlin fun setup(hello: Text, fab: Circle) { var result = "none" // the last result // counting animation GlobalScope.launch(Dispatchers.Main) { var counter = 0 while (true) { hello.text = "${++counter}: $result" delay(100) // update the text every 100ms } } // compute the next fibonacci number of each click var x = 1 fab.onClick { result = "fib($x) = ${fib(x)}" x++ } } ``` -------------------------------- ### Calling a Progress Function with UI Update Callback Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-and-channels.md This example demonstrates calling `loadContributorsProgress` and providing a callback that uses `withContext(Dispatchers.Main)` to safely update UI elements with intermediate results. ```kotlin launch(Dispatchers.Default) { loadContributorsProgress(service, req) { users, completed -> withContext(Dispatchers.Main) { updateResults(users, startTime, completed) } } } ``` -------------------------------- ### Define and execute coroutines using async and await Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/debug-coroutines-with-idea.md This Kotlin example shows how to use `runBlocking` to manage the coroutine scope, `async` to launch concurrent, deferred computations, and `await` to retrieve their results. ```kotlin import kotlinx.coroutines.* fun main() = runBlocking { val a = async { println("I'm computing part of the answer") 6 } val b = async { println("I'm computing another part of the answer") 7 } println("The answer is ${a.await() * b.await()}") } ``` -------------------------------- ### Manual TestScope creation for pre-test setup Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-test/README.md Create a TestScope instance before the test begins to enable dependency injection and mocking in @BeforeTest. Call scope.runTest() in the test method to execute the test body with the pre-configured scope. ```kotlin val scope = TestScope() @BeforeTest fun setUp() { Dispatchers.setMain(StandardTestDispatcher(scope.testScheduler)) TestSubject.setScope(scope) } @AfterTest fun tearDown() { Dispatchers.resetMain() TestSubject.resetScope() } @Test fun testSubject() = scope.runTest { // the receiver here is `testScope` } ``` -------------------------------- ### Define Async-style Functions with GlobalScope.async Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/composing-suspending-functions.md These functions use `GlobalScope.async` to start asynchronous computations, returning `Deferred` values. They are not suspending functions and require `@OptIn(DelicateCoroutinesApi::class)`. ```kotlin // The result type of somethingUsefulOneAsync is Deferred @OptIn(DelicateCoroutinesApi::class) fun somethingUsefulOneAsync() = GlobalScope.async { doSomethingUsefulOne() } // The result type of somethingUsefulTwoAsync is Deferred @OptIn(DelicateCoroutinesApi::class) fun somethingUsefulTwoAsync() = GlobalScope.async { doSomethingUsefulTwo() } ``` -------------------------------- ### Coroutine Builder: publish() Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/reactive/kotlinx-coroutines-reactive/README.md Creates a cold reactive publisher that starts the coroutine on subscribe. Returns a Publisher that operates within a ProducerScope, allowing emission of values to subscribers. ```APIDOC ## publish() ### Description Coroutine builder that creates a cold reactive publisher. The coroutine is started when a subscriber subscribes to the publisher. ### Result `Publisher` ### Scope `ProducerScope` ### Usage Use this builder to convert a coroutine into a Reactive Streams Publisher that emits values through the ProducerScope interface. ``` -------------------------------- ### Import JavaFX Main Dispatcher Alias Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md Imports the `Dispatchers.JavaFx` as `Main` to allow easy portability of examples between JavaFX and Android's `Dispatchers.Main`. ```kotlin import kotlinx.coroutines.javafx.JavaFx as Main ``` -------------------------------- ### Concurrent execution log output Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-and-channels.md Demonstrates how coroutines can start on one worker thread and resume on another within the default dispatcher pool. ```text 1946 [DefaultDispatcher-worker-2 @coroutine#4] INFO Contributors - starting loading for kotlin-koans 1946 [DefaultDispatcher-worker-3 @coroutine#5] INFO Contributors - starting loading for dokka 1946 [DefaultDispatcher-worker-1 @coroutine#3] INFO Contributors - starting loading for ts2kt ... 2178 [DefaultDispatcher-worker-1 @coroutine#4] INFO Contributors - kotlin-koans: loaded 45 contributors 2569 [DefaultDispatcher-worker-1 @coroutine#5] INFO Contributors - dokka: loaded 36 contributors 2821 [DefaultDispatcher-worker-2 @coroutine#3] INFO Contributors - ts2kt: loaded 11 contributors ``` -------------------------------- ### Get First Flow Value Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-flow-operators.md Retrieves the first emitted value and cancels further collection. ```kotlin import kotlinx.coroutines.* import kotlinx.coroutines.flow.* import kotlin.time.Duration.Companion.milliseconds import kotlin.time.TimeSource suspend fun main() { withContext(Dispatchers.Default) { val firstValue = flowOf(1, 2, 3).first() println(firstValue) // 1 } } ``` -------------------------------- ### Perform concurrent computations with CoroutineScope.async() Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-basics.md Starts a concurrent computation and returns a Deferred handle. Use await() to retrieve the result. ```kotlin // Imports the kotlin.time.Duration to enable expressing duration in milliseconds import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.* //sampleStart suspend fun main() = withContext(Dispatchers.Default) { // this: CoroutineScope // Starts downloading the first page val firstPage = this.async { delay(50.milliseconds) "First page" } // Starts downloading the second page in parallel val secondPage = this.async { delay(100.milliseconds) "Second page" } // Awaits both results and compares them val pagesAreEqual = firstPage.await() == secondPage.await() println("Pages are equal: $pagesAreEqual") } //sampleEnd ``` -------------------------------- ### Launch Basic UI Coroutine for Countdown (JavaFX) Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md Launches a coroutine on the main UI thread to perform a countdown animation, safely updating UI elements without blocking the thread. This example is for JavaFX. ```kotlin fun setup(hello: Text, fab: Circle) { GlobalScope.launch(Dispatchers.Main) { // launch coroutine in the main thread for (i in 10 downTo 1) { // countdown from 10 to 1 hello.text = "Countdown $i ..." // update text delay(500) // wait half a second } hello.text = "Done!" } } ``` -------------------------------- ### Coroutine debug log example Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-and-channels.md Sample log output showing the coroutine identifier (@coroutine#1) alongside the thread name. This requires the kotlinx.coroutines.debug VM option. ```text 2538 [AWT-EventQueue-0 @coroutine#1] INFO Contributors - kotlin: loaded 30 repos 2729 [AWT-EventQueue-0 @coroutine#1] INFO Contributors - ts2kt: loaded 11 contributors 3029 [AWT-EventQueue-0 @coroutine#1] INFO Contributors - kotlin-koans: loaded 45 contributors ... 11252 [AWT-EventQueue-0 @coroutine#1] INFO Contributors - kotlin-coroutines-workshop: loaded 1 contributors ``` -------------------------------- ### Kotlin Coroutines Select onAwait for First Deferred Completion Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/select-expression.md This example demonstrates using 'select' with 'onAwait' to wait for the first 'Deferred' value in a list to complete. It then prints the result and the count of remaining active coroutines. ```kotlin import kotlinx.coroutines.* import kotlinx.coroutines.selects.* import java.util.* fun CoroutineScope.asyncString(time: Int) = async { delay(time.toLong()) "Waited for $time ms" } fun CoroutineScope.asyncStringsList(): List> { val random = Random(3) return List(12) { asyncString(random.nextInt(1000)) } } fun main() = runBlocking { //sampleStart val list = asyncStringsList() val result = select { list.withIndex().forEach { (index, deferred) -> deferred.onAwait { answer -> "Deferred $index produced answer '$answer'" } } } println(result) val countActive = list.count { it.isActive } println("$countActive coroutines are still active") //sampleEnd } ``` -------------------------------- ### Skip initial values with drop Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-flow-operators.md Skips a specified number of initial values from the upstream flow. The example demonstrates skipping the first two elements. ```kotlin import kotlinx.coroutines.* import kotlinx.coroutines.flow.* // A simplified custom version of the default .drop() operator fun Flow.myDrop(count: Int): Flow = flow { require(count >= 0) var elementsAlreadyDropped = 0 this@myDrop.collect { value -> if (elementsAlreadyDropped == count) { this@flow.emit(value) } else { ++elementsAlreadyDropped } } } //sampleStart suspend fun main() = withContext(Dispatchers.Default) { // Skips the first two values from the upstream flow val flow = flowOf(1, 2, 3, 4, 5).drop(2) println(flow.toList()) // [3, 4, 5] } //sampleEnd ``` -------------------------------- ### Limit collection size with take Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-flow-operators.md Cancels the upstream flow after a specified number of values have been collected. The example collects only the first three values from a range. ```kotlin import kotlinx.coroutines.* import kotlinx.coroutines.flow.* import kotlin.random.* import java.io.IOException import kotlin.time.Duration.Companion.milliseconds // A simplified custom version of the default .take() operator fun Flow.myTake(count: Int): Flow = flow { require(count > 0) val cancellationException = CancellationException() var elementsRemaining = count try { this@myTake.collect { emit(it) --elementsRemaining if (elementsRemaining == 0) { // Cancels the upstream flow after the requested number of values throw cancellationException } } } catch (e: Throwable) { if (e === cancellationException) { // Handles the CancellationException used to cancel the upstream flow // Completes the flow after the set number of values in .myTake() } else { // Rethrows unexpected exceptions throw e } } } //sampleStart suspend fun main() = withContext(Dispatchers.Default) { // Collects only the first three values from the upstream flow val flow = (0..1000).asFlow().take(3) println(flow.toList()) // [0, 1, 2] } //sampleEnd ``` -------------------------------- ### Filter consecutive duplicates with distinctUntilChanged Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-flow-operators.md Emits values only when they differ from the previously emitted value. The example includes a custom implementation for demonstration. ```kotlin import kotlinx.coroutines.* import kotlinx.coroutines.flow.* // A simplified custom version of the default .distinctUntilChanged() operator fun Flow.myDistinctUntilChanged(): Flow = flow { var lastEmitted: Any? = Any() // A value that's equal only to itself this@myDistinctUntilChanged.collect { value -> if (lastEmitted != value) { this@flow.emit(value) lastEmitted = value } } } suspend fun main() = withContext(Dispatchers.Default) { // Removes repeated consecutive values from the upstream flow val flow = flowOf(1, 2, 3, 3, 3, 4, 5, 5, 1).distinctUntilChanged() println(flow.toList()) // [1, 2, 3, 4, 5, 1] } ``` -------------------------------- ### Start Background Thread for Blocking Operation in Kotlin Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-and-channels.md Demonstrates how to offload a blocking operation, `loadContributorsBlocking`, to a new background thread using Kotlin's `thread` function to prevent UI freezes. ```kotlin thread { loadContributorsBlocking(service, req) } ``` -------------------------------- ### Kotlin Coroutines Fan-in Example with Multiple Senders Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/channels.md Illustrates a complete fan-in scenario where multiple coroutines send strings to a single channel. The main coroutine receives and prints the first six messages before cancelling children. ```kotlin import kotlinx.coroutines.* import kotlinx.coroutines.channels.* fun main() = runBlocking { //sampleStart val channel = Channel() launch { sendString(channel, "foo", 200L) } launch { sendString(channel, "BAR!", 500L) } repeat(6) { // receive first six println(channel.receive()) } coroutineContext.cancelChildren() // cancel all children to let main finish //sampleEnd } suspend fun sendString(channel: SendChannel, s: String, time: Long) { while (true) { delay(time) channel.send(s) } } ``` -------------------------------- ### Using onStart and onEach operators Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-flow-operators.md Demonstrates executing logic before flow collection and before each value is emitted downstream. ```kotlin import kotlinx.coroutines.* import kotlinx.coroutines.flow.* import kotlin.time.Duration.Companion.milliseconds import kotlin.time.TimeSource // A simplified custom version of the default .onStart() operator fun Flow.myOnStart( action: suspend FlowCollector.() -> Unit ): Flow = flow { this@flow.action() this@myOnStart.collect(this@flow) } suspend fun main() { withContext(Dispatchers.Default) { flowOf("Page 1", "Page 2", "Page 3").onStart { println("Processing pages!") }.onEach { println("Emitted $it") }.collect { println("Collected $it") } } } ``` -------------------------------- ### Execute concurrent requests with logging in Kotlin Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-and-channels.md Starts a coroutine on the default dispatcher while logging the start of the operation. This pattern is useful for tracking parallel execution across threads. ```kotlin async(Dispatchers.Default) { log("starting loading for ${repo.name}") service.getRepoContributors(req.org, repo.name) .also { logUsers(repo, it) } .bodyList() } ``` -------------------------------- ### Build and run native benchmarks on macOS Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/benchmarks/README.md Build and execute benchmarks for macOS ARM64 architecture using Gradle. ```bash ./gradlew :kotlinx-coroutines-core:macosArm64BenchmarkBenchmark ``` -------------------------------- ### Load Contributors Using Retrofit Callbacks Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-and-channels.md Uses Call.enqueue() with onResponse() extension to start concurrent HTTP requests for repositories and their contributors. The updateResults() callback is called immediately after starting all requests, before responses are received, causing the allUsers list to be empty. ```kotlin fun loadContributorsCallbacks( service: GitHubService, req: RequestData, updateResults: (List) -> Unit ) { service.getOrgReposCall(req.org).onResponse { responseRepos -> // #1 logRepos(req, responseRepos) val repos = responseRepos.bodyList() val allUsers = mutableListOf() for (repo in repos) { service.getRepoContributorsCall(req.org, repo.name) .onResponse { responseUsers -> // #2 logUsers(repo, responseUsers) val users = responseUsers.bodyList() allUsers += users } } } // TODO: Why doesn't this code work? How to fix that? updateResults(allUsers.aggregate()) } ``` -------------------------------- ### Debugging Coroutines with DebugProbes Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-debug/README.md Demonstrates how to use `DebugProbes.install()` to enable debugging and `DebugProbes.dumpCoroutines()` or `DebugProbes.printJob()` to inspect the state of active coroutines in a Kotlin application. ```kotlin suspend fun computeValue(): String = coroutineScope { val one = async { computeOne() } val two = async { computeTwo() } combineResults(one, two) } suspend fun combineResults(one: Deferred, two: Deferred): String = one.await() + two.await() suspend fun computeOne(): String { delay(5000) return "4" } suspend fun computeTwo(): String { delay(5000) return "2" } fun main() = runBlocking { DebugProbes.install() val deferred = async { computeValue() } // Delay for some time delay(1000) // Dump running coroutines DebugProbes.dumpCoroutines() println("\nDumping only deferred") DebugProbes.printJob(deferred) } ``` -------------------------------- ### Coroutine Builders Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/reactive/kotlinx-coroutines-rx2/README.md Cold builders that start a coroutine on subscribe to produce RxJava 2.x types. ```APIDOC ## BUILDER rxCompletable, rxMaybe, rxSingle, rxObservable, rxFlowable ### Description Cold builders that start a coroutine on subscribe to produce various RxJava 2.x types. The coroutine is cancelled when the subscription is disposed. ### Method Coroutine Builder ### Endpoint kotlinx.coroutines.rx2 ### Parameters #### Path Parameters - **scope** (CoroutineScope/ProducerScope) - Required - The scope in which the coroutine is launched. ### Response #### Success Response (200) - **result** (RxType) - Returns Completable, Maybe, Single, Observable, or Flowable (with backpressure support). ``` -------------------------------- ### Initialize MutableStateFlow with initial value Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-flow.md Use the MutableStateFlow() function to create a flow with a mandatory starting state. ```kotlin // Creates a MutableStateFlow with LoadingState.Started as the initial value val result = MutableStateFlow(LoadingState.Started) ``` -------------------------------- ### Coroutine Builders - flux Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/reactive/kotlinx-coroutines-reactor/README.md Creates a cold Flux that starts the coroutine on subscription. Returns a Flux instance within a CoroutineScope. ```APIDOC ## flux ### Description A cold Flux that starts the coroutine on subscription. ### Result Type `Flux` ### Scope `CoroutineScope` ### Usage Use this builder to create a Flux from a coroutine block. The coroutine will only start executing when the Flux is subscribed to. ``` -------------------------------- ### Handle exceptions in root coroutines with launch and async Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/exception-handling.md Demonstrates how launch treats exceptions as uncaught, while async requires explicit handling by the caller. ```kotlin import kotlinx.coroutines.* //sampleStart @OptIn(DelicateCoroutinesApi::class) fun main() = runBlocking { val job = GlobalScope.launch { // root coroutine with launch println("Throwing exception from launch") throw IndexOutOfBoundsException() // Will be printed to the console by Thread.defaultUncaughtExceptionHandler } job.join() println("Joined failed job") val deferred = GlobalScope.async { // root coroutine with async println("Throwing exception from async") throw ArithmeticException() // Nothing is printed, relying on user to call await } try { deferred.await() println("Unreached") } catch (e: ArithmeticException) { println("Caught ArithmeticException") } } //sampleEnd ``` -------------------------------- ### Infinite integer stream generator Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/channels.md Creates a producer coroutine that emits an infinite sequence of integers starting from a given value. ```kotlin fun CoroutineScope.numbersFrom(start: Int) = produce { var x = start while (true) send(x++) // infinite stream of integers from start } ``` -------------------------------- ### Discover available benchmark tasks Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/benchmarks/README.md List all available benchmark-related Gradle tasks for the kotlinx-coroutines-core project. ```bash ./gradlew :kotlinx-coroutines-core:tasks | grep -i bench ``` -------------------------------- ### Main Pipeline Execution Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/channels.md Sets up and runs a coroutine pipeline. It produces numbers, squares them, and prints the first five results. Ensures child coroutines are cancelled upon completion. ```kotlin import kotlinx.coroutines.* import kotlinx.coroutines.channels.* fun main() = runBlocking { //sampleStart val numbers = produceNumbers() // produces integers from 1 and on val squares = square(numbers) // squares integers repeat(5) { println(squares.receive()) // print first five } println("Done!") // we are done coroutineContext.cancelChildren() // cancel children coroutines //sampleEnd } fun CoroutineScope.produceNumbers() = produce { var x = 1 while (true) send(x++) } fun CoroutineScope.square(numbers: ReceiveChannel): ReceiveChannel = produce { for (x in numbers) send(x * x) } ``` -------------------------------- ### Clone the project template using Git Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-and-channels.md Use this command to clone the introductory coroutines project repository from GitHub to your local machine. ```Bash git clone https://github.com/kotlin-hands-on/intro-coroutines ``` -------------------------------- ### Coroutine Builders Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/reactive/kotlinx-coroutines-rx3/README.md Cold coroutine builders that create RxJava 3 reactive types. These builders start a coroutine only when a subscriber is present. ```APIDOC ## BUILDER rxCompletable, rxMaybe, rxSingle, rxObservable, rxFlowable ### Description Cold coroutine builders that start a coroutine on subscribe to produce RxJava 3 reactive types. ### Method BUILDER ### Endpoint kotlinx.coroutines.rx3 ### Parameters #### Request Body - **rxCompletable** (Completable) - Cold completable that starts coroutine on subscribe - **rxMaybe** (Maybe) - Cold maybe that starts coroutine on subscribe - **rxSingle** (Single) - Cold single that starts coroutine on subscribe - **rxObservable** (Observable) - Cold observable that starts coroutine on subscribe - **rxFlowable** (Flowable) - Cold observable with backpressure support ### Response #### Success Response (200) - **Result** (Reactive Type) - The corresponding RxJava 3 reactive type (Completable, Maybe, Single, Observable, or Flowable). ``` -------------------------------- ### Package Overview Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/README.md Overview of the main packages in the kotlinx.coroutines library and their purposes. ```APIDOC ## Package Structure ### kotlinx.coroutines **Description**: General-purpose coroutine builders, contexts, and helper functions ### kotlinx.coroutines.sync **Description**: Synchronization primitives (mutex and semaphore) ### kotlinx.coroutines.channels **Description**: Channels — non-blocking primitives for communicating a stream of elements between coroutines ``` -------------------------------- ### Produce Infinite Stream of Integers Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/channels.md Defines a coroutine that produces an infinite stream of integers starting from 1. This function is an extension on `CoroutineScope`. ```kotlin fun CoroutineScope.produceNumbers() = produce { var x = 1 while (true) send(x++) } ``` -------------------------------- ### Launch Coroutine from UI Thread (UNDISPATCHED) Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md Demonstrates using `CoroutineStart.UNDISPATCHED` to immediately execute a coroutine launched from a UI event handler until its first suspension point, optimizing performance in specific scenarios. ```kotlin fun setup(hello: Text, fab: Circle) { fab.onMouseClicked = EventHandler { println("Before launch") GlobalScope.launch(Dispatchers.Main, CoroutineStart.UNDISPATCHED) { // <--- Notice this change println("Inside coroutine") delay(100) // <--- And this is where coroutine suspends println("After delay") } println("After launch") } } ``` -------------------------------- ### Define multithreaded entry point Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-basics.md Use withContext to switch to a shared thread pool for concurrent execution. ```kotlin suspend fun main() { withContext(Dispatchers.Default) { // Add the coroutine builders here } } ``` -------------------------------- ### Import kotlinx.coroutines Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-basics.md Include the library in your Kotlin source files. ```kotlin import kotlinx.coroutines.* ``` -------------------------------- ### Inheriting Context in Nested Coroutines Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-and-channels.md This example shows how a `coroutineScope` and nested `async` coroutines automatically inherit the context, including the dispatcher, from their outer scope. ```kotlin suspend fun loadContributorsConcurrent( service: GitHubService, req: RequestData ): List = coroutineScope { // this scope inherits the context from the outer scope // ... async { // nested coroutine started with the inherited context // ... } // ... } ``` -------------------------------- ### Test timeout with runTest Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-test/README.md Tests automatically timeout after 60 seconds by default. This example shows a test that will fail with a timeout exception due to an indefinite await. ```kotlin @Test fun testHanging() = runTest { CompletableDeferred().await() // will hang forever } ``` -------------------------------- ### Collect a flow using launchIn Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-flow-operators.md Demonstrates using launchIn to collect a StateFlow within a custom class scope, ensuring the collection stops when the scope is cancelled. ```kotlin data class Coordinate(val x: Int, val y: Int) class MyScreen(val scope: CoroutineScope) { private val _mousePosition = MutableStateFlow(Coordinate(0, 0)) val mousePosition get() = _mousePosition.asStateFlow() init { // Starts collecting the StateFlow in the screen's CoroutineScope mousePosition.onEach { updateStatusBar() }.launchIn(scope) } fun moveMouse(newCoordinate: Coordinate) { _mousePosition.value = newCoordinate } private fun updateStatusBar() { println("Mouse is at ${_mousePosition.value}") } } suspend fun main() { withContext(Dispatchers.Default) { val childScope = CoroutineScope( currentCoroutineContext() + Job(currentCoroutineContext()[Job]) ) val screen = MyScreen(childScope) delay(100.milliseconds) screen.moveMouse(Coordinate(10, 15)) delay(100.milliseconds) screen.moveMouse(Coordinate(1, 3)) delay(100.milliseconds) childScope.cancel() } } ``` -------------------------------- ### Implement Producer-Consumer pattern with Kotlin Channels Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/docs/topics/coroutines-and-channels.md Demonstrates multiple producers sending data to a single channel and a consumer receiving it. Uses runBlocking and launch for coroutine management. ```kotlin import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.* fun main() = runBlocking { val channel = Channel() launch { channel.send("A1") channel.send("A2") log("A done") } launch { channel.send("B1") log("B done") } launch { repeat(3) { val x = channel.receive() log(x) } } } fun log(message: Any?) { println("[${Thread.currentThread().name}] $message") } ``` -------------------------------- ### onClick extension with GlobalScope.launch for JavaFX Source: https://github.com/kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md Basic onClick extension for Node that launches a new coroutine on each mouse event. Multiple concurrent coroutines may compete to update UI; use actor pattern for better concurrency control. ```kotlin fun Node.onClick(action: suspend (MouseEvent) -> Unit) { onMouseClicked = EventHandler { event -> GlobalScope.launch(Dispatchers.Main) { action(event) } } } ```