https://kotlinlang.org logo
Join Slack
Powered by
# coroutines
  • j

    joseph_ivie

    08/19/2025, 9:58 PM
    Would it make more sense for
    CancellationException
    to not be an
    Exception
    ? It really doesn't fall under that category. It doesn't represent some kind of issue; it represents that we don't care about the result anymore. It seems like it should inherit from
    Throwable
    and be treated entirely differently.
    y
    c
    • 3
    • 9
  • b

    baxter

    08/20/2025, 6:40 PM
    Had a coworker pose this code snippet for me and ask me what would break if anything. I'd like to see what you all think as well:
    Copy code
    override fun getSomeFlow(): Flow<String> =
            localDataFlow
                .onStart {
                    // Fire-and-forget, but still tied to the collector's lifecycle.
                    CoroutineScope(currentCoroutineContext()).launch {
                        triggerSomePrefetchCaching()
                    }
                }
                .map { data ->
                    data.toSomeString()
                }
    j
    c
    • 3
    • 4
  • s

    svenjacobs

    08/21/2025, 6:11 AM
    Hey guys, after several hours of debugging I encountered a behavior of Coroutines that leaves me confused and questions my understanding of Coroutines.
    l
    m
    +5
    • 8
    • 57
  • u

    ursus

    08/21/2025, 9:40 PM
    Folks who inject `CoroutineScope`s with semantic meaning, how do you deal with mismatch against DI?
    Copy code
    @SingleIn(UserScope::class)
    class MyDependency(
       @QualifierFor(AppScope::class) private val scope: CoroutineScope
    ) {
       fun foo() {
          scope.launch {
             // access other fields
          }
       }
    }
    since this compiles but is a memory leak
    z
    s
    l
    • 4
    • 117
  • u

    ursus

    08/22/2025, 1:08 PM
    Does
    combine
    conflate or not? Will every component emit get a matching emission out of the
    combine
    ? (I though it will always emit all of the combinations, but I'm seeing some nondeterministic behavior at tests - and now I'm not sure if it's test issue or
    combine
    issue)
    r
    • 2
    • 1
  • a

    Andrey Tabakov

    08/26/2025, 11:39 AM
    Hello, we catch some really weird error:
    Copy code
    2025-08-25 22:44:15.278 [DefaultDispatcher-worker-10] WARN  a.r.backend.api.KtorApp - null
    java.lang.IllegalMonitorStateException: null
    	at java.base/java.util.concurrent.locks.ReentrantReadWriteLock$Sync.tryRelease(Unknown Source)
    	at java.base/java.util.concurrent.locks.AbstractQueuedSynchronizer.release(Unknown Source)
    	at java.base/java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock.unlock(Unknown Source)
    	at ai.retable.backend.dataflow.processing.design.App.veryImportant(App.kt:619)
    Code that cause error:
    Copy code
    val lock = ReentrantReadWriteLock() // java.util.concurrent.locks
    
    suspend fun veryImportant() {
      lock.write {
          withTimeout(TIMEOUT) {
            // do some suspend work
          }
      }
    }
    Java code that cause an error:
    Copy code
    @ReservedStackAccess
    protected final boolean tryRelease(int releases) {
        if (!isHeldExclusively())
            throw new IllegalMonitorStateException();
        int nextc = getState() - releases;
        boolean free = exclusiveCount(nextc) == 0;
        if (free)
            setExclusiveOwnerThread(null);
        setState(nextc);
        return free;
    }
    
    protected final boolean isHeldExclusively() {
     // While we must in general read state before owner,
     // we don't need to do so to check if current thread is owner
     return getExclusiveOwnerThread() == Thread.currentThread();
    }
    So, does it mean I can't use
    java.util.concurrent.locks.ReentrantReadWriteLock
    with Kotlin coroutines because the thread can change?
    r
    k
    • 3
    • 27
  • k

    kevin.cianfarini

    08/28/2025, 5:40 PM
    Since
    Clock
    and
    Instant
    are about to go stable in the stdlib, is there any willingness to add a Clock implementation in the test coroutines artifact that reflects the current time of the test scheduler?
    plus one 4
    h
    • 2
    • 3
  • b

    Brais Gabin

    08/29/2025, 7:10 AM
    Is there any API for an atomic
    Set
    ? I know that I can use
    AtomicRefenrece
    but its api is not really good.
    z
    w
    • 3
    • 3
  • h

    Hong Phuc

    08/30/2025, 4:44 AM
    Hi guys, is this statement true, specifically regrading the part where they say: "The suspend functions that directly suspend a coroutine are in the standard library"?
    Marking a function
    suspend
    gives it the capability to suspend the coroutine, but it will only actually suspend the coroutine if it internally calls another suspend function that suspends the coroutine. The suspend functions that directly suspend a coroutine are in the standard library. Among these are
    suspendCoroutine()
    and
    suspendCancellableCoroutine()
    . You will not often use these. They are most commonly used to convert non-coroutine APIs into suspend functions.
    Some of the commonly used functions that indirectly suspend a coroutine are
    withContext()
    ,
    delay()
    ,
    Job.join()
    and
    Deferred.await()
    .
    I found it in this Stackoverflow post.
    j
    • 2
    • 1
  • t

    Tian Tian098

    09/05/2025, 6:36 PM
    I have a kotlin flow
    Copy code
    flow { /* do some IO and emits some results */ }
      .collect { /* do some post processing */ }
    If I introduce some retry logic using delay() into the body of the flow, it deadlocks if delay() gets called. In particular, it deadlocks after delay gets called, I think the first time I do some IO after delay returns.
    Copy code
    flow { /* do some IO, retry if necessary, and emit some results */ }
      .collect { /* do some post processing */ }
    But if I tell the flow to flow on some dispatcher, then it suddenly works again
    Copy code
    flow { /* do some IO, retry if necessary, and emit some results */ }
      .flowOn(Dispatchers.Unconfined)
      .collect { /* do some post processing */ }
    Why would that be the case?
    ✅ 1
    y
    z
    +2
    • 5
    • 20
  • d

    David Breneisen

    09/06/2025, 10:13 AM
    I guess the reason for stateIn having an initialValue parameter is that it's needed for regular Flows, but for my case I am always using it after combining or mapping StateFlows. It's not a big deal when the output is a primitive type but when it's something more complicated creating an initial value that I know is never going to be used isn't great. Maybe there should be a version of those functions that outputs a StateFlow instead of Flow so it doesn't need to be converted with stateIn?
    s
    i
    +2
    • 5
    • 21
  • i

    Irsath Kareem

    09/08/2025, 10:20 AM
    Can anyone help me?
    Copy code
    // Data Layer
    val locationUpdatesFlow = callbackFlow {
       // Registered Location Callback
       awaitClose { 
          // Cleanup 
       }
    }.shareIn(
        scope = applicationScope, 
        sharingStarted = SharingStarted.WhileSubscribed(),
    )
    The reason, Why I am using SharedFlow in Data layer is, This flow can be collected in background also (by some other services....) while we collecting via UI. So, it will be performant that, the
    locationUpdatesFlow
    is SHARED. (I think so). Also, I need, this flow is running, if at least one subscriber is available. Otherwise, Kill this Flow. For this reason, I use
    SharingStarted.WhileSubscribed()
    Now In UI Layer (ViewModel)
    Copy code
    val locationsState = DataLayer.locationUpdatesFlow
         .stateIn(
            scope = viewModelScope,
            sharingStarted = SharingStarted.WhileSubscribed(5000),
            initialValue = null
         )
    The reason, Why I am using STATEFLOW here is, I need the location value in my UI as observable value In Screen, I use
    viewModel.locationsState.collectAsStateWithLifecycle()
    The Problem, I faced is below, 1. DataLayer.locationUpdatesFlow is NOT started....... While my UI is UP and RUNNING Is there any problem, that two nested
    SharableFlow
    (One on another) - (StateFlow on SharedFlow, in this case) Can any one explain this, And how to resolve this? (Also considering my Data Layer usecases/needs)
    ✅ 1
    u
    r
    • 3
    • 6
  • u

    ursus

    09/11/2025, 4:13 PM
    Copy code
    private suspend fun DefaultClientWebSocketSession.send(outgoingSubmission: OutgoingSubmission) {
        when (outgoingSubmission) {
            is OutgoingSubmission.Text -> {
                val outgoingEnvelope = OutgoingEnvelope.HandleMessage(
                    ...
                )
                send(OutgoingEnvelope.HandleMessage.serializer(), outgoingEnvelope) <-------
            }
            ...
        }
    }
    detekt
    flags this code with
    suspend function uses CoroutineScope as receiver. [SuspendFunWithCoroutineScopeReceiver]
    is this a false positive? what's wrong with it? Sure ktor's
    DefaultClientWebSocketSession
    is a coroutine scope but im pretty sure it's not meant to launch sends into it?
    e
    • 2
    • 2
  • d

    Dontsu

    09/13/2025, 2:25 AM
    When an exception occurs in a coroutine, does it propagate the exception to the parent first, or does the cancellation propagate to its children first? I tested the code below, and the termination order always changes depending on the position of the
    delay()
    functions. So, I couldn’t tell which happens first, exception propagation or cancellation propagation. I realized that depending on the coroutine’s progress, it’s impossible to know which one will terminate first. But, I’m still curious whether, at the exact moment an error occurs, the coroutine internally attempts to propagate cancellation to its children first or propagate the exception to its parent first.
    Copy code
    fun main(): Unit = runBlocking {
        val job1 = launch(CoroutineName("Coroutine1")) {
    
            val job2 = launch(CoroutineName("Coroutine2")) {
                val job4 = launch(CoroutineName("Coroutine4")) {
                    println("Coroutine4 run")
                    delay(600)
                }
                job4.invokeOnCompletion {
                    println("Coroutine4 end")
                }
                val job5 = launch(CoroutineName("Coroutine5")) {
                    println("Coroutine5 run")
                    delay(600)
                }
                job5.invokeOnCompletion {
                    println("Coroutine5 end")
                }
                println("Coroutine2 run")
            }
            job2.invokeOnCompletion {
                println("Coroutine2 end")
            }
    
            val job3 = launch(CoroutineName("Coroutine3")) {
                val job6 = launch(CoroutineName("Coroutine6")) {
                    delay(600)
                    println("Coroutine6 run")
                }
                job6.invokeOnCompletion {
                    println("Coroutine6 end")
                }
                println("Coroutine3 run")
                delay(500)
                throw Exception() // here! exception occurs!
            }
    
            job3.invokeOnCompletion {
                println("Coroutine3 end")
            }
            println("Coroutine1 run")
        }
    
        job1.invokeOnCompletion {
            println("Coroutine1 end")
        }
    
    }
    👀 2
    d
    • 2
    • 5
  • x

    xenomachina

    09/13/2025, 3:38 AM
    I'm not sure where to ask this, so apologies if this is not the right channel. I'm asking here because my Googling suggested that this issue may somehow be coroutine related. I'm trying to debug some code in a suspend function (which happens to be part of a kotest spec), and I need to see the value of a variable,
    messages
    . However, IntelliJ is saying "'messages was optimised out". This is despite the fact that my code uses this the variable after the breakpoint.
    Copy code
    val messages = msg.messages()
    println(messages)                  // breakpoint is on this line
    messages.size shouldBe 1
    Is there any way to tell it to not optimize out a variable?
    e
    d
    • 3
    • 3
  • a

    Abhimanyu

    09/16/2025, 3:48 AM
    Hi all kodee greetings , I have a coroutine that has few children coroutines and suspend method calls. How to rethrow an exception thrown by one of the suspending method calls? Code example in 🧵
    s
    d
    • 3
    • 7
  • c

    Colton Idle

    09/16/2025, 11:00 PM
    Came across some code in a PR that seems weird to me. Let me know if it's just me or if this is idiomatic coroutines code.
    Copy code
    class MyCoolHandler{ 
    var mContinuation: Continuation<Foo>? = null
    suspend fun waitingForFoo(): Foo = suspendCoroutine { continuation -> 
    // code
    mContinuation = continuation
    }
    // some other class functions
    }
    z
    s
    +2
    • 5
    • 11
  • a

    Alex Styl

    09/18/2025, 9:46 AM
    mutableXOf
    are not thread safe right? I have a mutable set which i populate from within multiple coroutines (thousands) and I am missing some items after my code is executed. I wrapped the
    .add
    calls from a single thread context scope and it seems to be working fine now. are there any thread safe versions of mutable set of? or better yet, are there any recommended approaches to this?
    👌 1
    d
    m
    • 3
    • 3
  • u

    ursus

    09/18/2025, 9:17 PM
    Say I want to run 2 api calls in parallel, then map their results together, and then save that to db. Question is, should I try to scope down the "
    coroutineScope { .. }
    length, or is it okay to have ot extend to the full function body? Whats more idiomatic?
    j
    k
    • 3
    • 5
  • j

    Joshua Hansen

    09/18/2025, 9:27 PM
    When writing a suspend function, do we make any assumptions about whether or not that function is already being executed in a given scope? Say I'm writing a function which needs to do some file reading and then perform some UI stuff. Should I explicitly use
    withContext
    for every switch between UI and background? Currently I have:
    Copy code
    suspend fun openView(path: Path): MyView {
        // Load data
    
        return withContext(Dispatchers.Swing) {
            // Create UI View
        }
    }
    s
    • 2
    • 11
  • j

    Joshua Hansen

    09/19/2025, 7:22 PM
    Is there a more idiomatic way to achieve the result of asynchronously loading a bunch of file data from a list of paths? I've been using this:
    Copy code
    val data: List<MyDataClass> = withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
        filePaths.map { path ->
            async {
                path.inputStream().use {
                    // Read in file data as instance of MyDataClass
                }
            }
        }.awaitAll()
    }
    y
    • 2
    • 1
  • h

    Hong Phuc

    09/22/2025, 2:15 AM
    Hi guys, can someone comment on how true this comment is https://www.reddit.com/r/Kotlin/comments/1kko2s7/comment/mrytehj/?utm_source=share&u[…]m=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button? The commenter talked about why they wouldn't use ktor/coroutine, one of the issue they mentioned is that debugger doesn't follow the coroutine, but the carrier thread, which I have experienced before, another issue is that parameter will be marked as "optimised out", also the fact that code is "colored" with coroutine. I can't confirm about other issues that was mentioned, so I'm looking for everyone's opinion. Thanks in advance.
    s
    g
    +2
    • 5
    • 14
  • r

    Rob Elliot

    09/23/2025, 11:17 AM
    This is probably a stupid question, but is there anyway to wrap up this:
    Copy code
    sealed interface FooResult
    data object FooCancelled : FooResult
    data class FooSuccess : FooResult
    
    suspend fun foo(): FooResult = TODO()
    
    val deferred = async { foo() }
    deferred.cancel()
    val result = deferred.await()
    so that the last call will never throw
    CancellationException
    , instead returning
    FooCancelled
    ? Without a try / catch (or equivalent) around
    deferred.await()
    ?
    y
    z
    l
    • 4
    • 16
  • t

    Tian Tian098

    09/24/2025, 3:52 AM
    Is it possible to have a MutableStateFlow that continuously produces values? I would like to zip it with another flow as I don't want the resulting flow to be limited by how often my MutableStateFlow gets mutated.
    Copy code
    val foo = MutableStateFlow(0)
    val bar = flow { ... }
    foo.zip(bar) { ... } // I don't want the resulting flow to be limited by how often foo is updated.
    solved 1
    g
    • 2
    • 4
  • j

    Jonas

    09/24/2025, 12:48 PM
    Hey everyone, when I'm converting a callback based API to a
    Flow
    using
    callbackFlow
    , do I have to call
    close()
    after
    trySend(...)
    when the call back only emits once?
    g
    l
    • 3
    • 15
  • j

    Julius Babies

    09/27/2025, 7:20 PM
    Don't know if this is the right channel, but does something an async task queue exist where I provide a coroutine scope in which callbacks can be scheduled to be executed sequentially or simultaneously?
    c
    p
    +2
    • 5
    • 5
  • a

    Artyom Gornostayev

    09/29/2025, 10:03 AM
    Hi guys. Does anybody have an experience in creating observability for active coroutines at runtime (PROD)? I need to know how many active coroutines are in the thread pool. I see there is an
    kotlin-coroutines-debug
    library, which solves my requirements. However, I'm not sure about performance impact + if it is suitable to native builds (according to the docs - not really)... I would be very grateful for advice. :)
    n
    • 2
    • 3
  • c

    CLOVIS

    10/01/2025, 12:51 PM
    Is it possible to disable the automatic dump of coroutines at the end of tests when debug probes are enabled? I'd like to control the exact time at which it happens.
    d
    o
    • 3
    • 10
  • r

    reactormonk

    10/09/2025, 12:36 PM
    How would I encode interruptible code vs. non-interruptible code? Aka ask some Job nicely to cancel, but the job itself can say no, or await until an interruptible section has been reached.
    d
    • 2
    • 16
  • r

    reactormonk

    10/15/2025, 4:16 PM
    I'm trying to figure out why this
    first()
    doesn't get cancelled by the timeout
    j
    • 2
    • 9