1<contribute-url>https://github.com/Kotlin/kotlinx.coroutines/edit/master/docs/topics/</contribute-url> 2 3 4[//]: # (title: Debug Kotlin Flow using IntelliJ IDEA – tutorial) 5 6This tutorial demonstrates how to create Kotlin Flow and debug it using IntelliJ IDEA. 7 8The tutorial assumes you have prior knowledge of the [coroutines](coroutines-guide.md) and [Kotlin Flow](flow.md#flows) concepts. 9 10## Create a Kotlin flow 11 12Create a Kotlin [flow](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/flow.html) with a slow emitter and a slow collector: 13 141. Open a Kotlin project in IntelliJ IDEA. If you don't have a project, [create one](jvm-get-started.md#create-a-project). 152. To use the `kotlinx.coroutines` library in a Gradle project, add the following dependency to `build.gradle(.kts)`: 16 17 <tabs group="build-script"> 18 <tab title="Kotlin" group-key="kotlin"> 19 20 ```kotlin 21 dependencies { 22 implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:%coroutinesVersion%") 23 } 24 ``` 25 26 </tab> 27 <tab title="Groovy" group-key="groovy"> 28 29 ```groovy 30 dependencies { 31 implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:%coroutinesVersion%' 32 } 33 ``` 34 35 </tab> 36 </tabs> 37 38 For other build systems, see instructions in the [`kotlinx.coroutines` README](https://github.com/Kotlin/kotlinx.coroutines#using-in-your-projects). 39 403. Open the `Main.kt` file in `src/main/kotlin`. 41 42 The `src` directory contains Kotlin source files and resources. The `Main.kt` file contains sample code that will print `Hello World!`. 43 444. Create the `simple()` function that returns a flow of three numbers: 45 46 * Use the [`delay()`](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/delay.html) function to imitate CPU-consuming blocking code. It suspends the coroutine for 100 ms without blocking the thread. 47 * Produce the values in the `for` loop using the [`emit()`](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow-collector/emit.html) function. 48 49 ```kotlin 50 import kotlinx.coroutines.* 51 import kotlinx.coroutines.flow.* 52 import kotlin.system.* 53 54 fun simple(): Flow<Int> = flow { 55 for (i in 1..3) { 56 delay(100) 57 emit(i) 58 } 59 } 60 ``` 61 625. Change the code in the `main()` function: 63 64 * Use the [`runBlocking()`](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/run-blocking.html) block to wrap a coroutine. 65 * Collect the emitted values using the [`collect()`](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/collect.html) function. 66 * Use the [`delay()`](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/delay.html) function to imitate CPU-consuming code. It suspends the coroutine for 300 ms without blocking the thread. 67 * Print the collected value from the flow using the [`println()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/println.html) function. 68 69 ```kotlin 70 fun main() = runBlocking { 71 simple() 72 .collect { value -> 73 delay(300) 74 println(value) 75 } 76 } 77 ``` 78 796. Build the code by clicking **Build Project**. 80 81  82 83## Debug the coroutine 84 851. Set a breakpoint at the line where the `emit()` function is called: 86 87  88 892. Run the code in debug mode by clicking **Debug** next to the run configuration at the top of the screen. 90 91  92 93 The **Debug** tool window appears: 94 * The **Frames** tab contains the call stack. 95 * The **Variables** tab contains variables in the current context. It tells us that the flow is emitting the first value. 96 * The **Coroutines** tab contains information on running or suspended coroutines. 97 98  99 1003. Resume the debugger session by clicking **Resume Program** in the **Debug** tool window. The program stops at the same breakpoint. 101 102  103 104 Now the flow emits the second value. 105 106  107 108### Optimized-out variables 109 110If you use `suspend` functions, in the debugger, you might see the "was optimized out" text next to a variable's name: 111 112 113 114This text means that the variable's lifetime was decreased, and the variable doesn't exist anymore. 115It is difficult to debug code with optimized variables because you don't see their values. 116You can disable this behavior with the `-Xdebug` compiler option. 117 118> __Never use this flag in production__: `-Xdebug` can [cause memory leaks](https://youtrack.jetbrains.com/issue/KT-48678/Coroutine-debugger-disable-was-optimised-out-compiler-feature#focus=Comments-27-6015585.0-0). 119> 120{style="warning"} 121 122## Add a concurrently running coroutine 123 1241. Open the `Main.kt` file in `src/main/kotlin`. 125 1262. Enhance the code to run the emitter and collector concurrently: 127 128 * Add a call to the [`buffer()`](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/buffer.html) function to run the emitter and collector concurrently. `buffer()` stores emitted values and runs the flow collector in a separate coroutine. 129 130 ```kotlin 131 fun main() = runBlocking<Unit> { 132 simple() 133 .buffer() 134 .collect { value -> 135 delay(300) 136 println(value) 137 } 138 } 139 ``` 140 1413. Build the code by clicking **Build Project**. 142 143## Debug a Kotlin flow with two coroutines 144 1451. Set a new breakpoint at `println(value)`. 146 1472. Run the code in debug mode by clicking **Debug** next to the run configuration at the top of the screen. 148 149  150 151 The **Debug** tool window appears. 152 153 In the **Coroutines** tab, you can see that there are two coroutines running concurrently. The flow collector and emitter run in separate coroutines because of the `buffer()` function. 154 The `buffer()` function buffers emitted values from the flow. 155 The emitter coroutine has the **RUNNING** status, and the collector coroutine has the **SUSPENDED** status. 156 1573. Resume the debugger session by clicking **Resume Program** in the **Debug** tool window. 158 159  160 161 Now the collector coroutine has the **RUNNING** status, while the emitter coroutine has the **SUSPENDED** status. 162 163 You can dig deeper into each coroutine to debug your code. 164