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

    rnett

    07/18/2025, 11:35 PM
    Hey folks, does anyone know if `lincheck`'s guarantees support extension methods? In particular, would something like
    forClasses(ReentrantLock::class).allMethods().ignore()
    correctly ignore
    fun <T> ReentrantLock.withLock(block: () -> T)
    ?
  • e

    Eugen Martynov

    07/21/2025, 11:54 AM
    What if I need to setup callback wrapped in the coroutine and only after call some action. Can I achieve it only with async? Or I need to use more thread synchronisation. Problem: I need to add listener for DB update but DB save happens async and I can not hook into it.
    Copy code
    val waithForDBSave = async { setupListenerAndWait() } 
    db.save() // I want to wait before executing here to be sure listener was setup
    waitForDBSave.await()
    d
    n
    z
    • 4
    • 11
  • a

    Atul Gupta

    07/22/2025, 8:37 PM
    When I try to debug compose multiplatform UT using
    runTest
    in commonTest and add the debug point for more than 1m, it crashes with below exception
    Copy code
    After waiting for 1m, the test body did not run to completion
    kotlinx.coroutines.test.UncompletedCoroutinesError: After waiting for 1m, the test body did not run to completion
    shouldn't it see that debug is attached and and don't count that time(when it is attached)?
    e
    n
    • 3
    • 5
  • l

    Lukasz Kalnik

    07/25/2025, 8:57 AM
    In a
    TestScope
    , how can I manually control the passing of virtual time inside a suspending function?
    Copy code
    suspend fun doSomethingDelayed() {
        delay(10.seconds)
        println("Delayed action completed")
    }
    a
    d
    • 3
    • 14
  • r

    Rob

    07/27/2025, 4:35 PM
    Hello All! I've published a Detekt ruleset that ensures correct handling of coroutine cancellation in catch blocks. Please try it out and provide feedback. Thanks! https://github.com/zirman/robs-rules/
    👌🏼 1
    👌 1
    u
    l
    • 3
    • 23
  • u

    谢朋刚

    08/01/2025, 3:01 AM
    Does anyone know the difference between using
    resumeWithException
    and directly throwing an
    Exception
    within a suspend function?
    y
    z
    d
    • 4
    • 9
  • c

    CLOVIS

    08/04/2025, 2:07 PM
    Today, it is still the case that the missing stacktraces when using coroutines are a major blocker for adoption in many teams. Are there plans on providing a mode in which stacktraces are correct (even if that's slower)?
    r
    z
    • 3
    • 7
  • a

    August Lilleaas

    08/04/2025, 4:48 PM
    just wanted to share this little cool snippet. Super easy to add a very simple homemade function that logs an error if a database query (or any async operation, really) takes more than 10 seconds 🙂 Coroutines ftw!
    Copy code
    suspend fun <T> CoroutineScope.logSlowQueries(
        timeoutSeconds: Long?,
        block: suspend () -> T
    ): T {
        val slowQueryDetectorJob = async {
            delay(Duration.ofSeconds(timeoutSeconds ?: 10))
            val otelCtx = Span.current().spanContext
    
            if (otelCtx.isValid) {
                log.error("Query not completed after $timeoutSeconds seconds - traceId=${otelCtx.traceId} spanId=${otelCtx.spanId}")
            } else {
                log.error("Query not completed after $timeoutSeconds seconds - NO OTEL CTX AVAILABLE")
            }
        }
    
        return try {
            block()
        } finally {
            slowQueryDetectorJob.cancel()
        }
    }
    mother of god 2
    s
    l
    • 3
    • 5
  • z

    Zach Klippenstein (he/him) [MOD]

    08/04/2025, 5:33 PM
    You can use
    coroutineScope
    in your function body so the caller doesn’t need to pass one in, and it t would be more idiomatic to use
    launch
    instead of
    async
    since the timing coroutine doesn’t need to return a value.
    👌 1
    🧵 5
    a
    • 2
    • 3
  • k

    kevin.cianfarini

    08/04/2025, 5:38 PM
    Yeah, I'd rewrite this function to:
    Copy code
    suspend fun logSlow(logAfter: Duration = 10.seconds, block: suspend () -> T): T = coroutineScope {
      val logJob = launch {
        delay(logAfter)
        log.error(...)
      }
      return try {
        block()
      } finally {
        logJob.cancel()
      }
    }
    ☝🏻 1
    🧵 5
    ☝️ 2
    ☝🏽 1
    ☝🏾 1
  • z

    Zach Klippenstein (he/him) [MOD]

    08/05/2025, 1:27 AM
    Threads? In this channel? 😜 (My bad, I thought I was in thread view when I replied, great to see everyone helping keep this place clean)
    ⏸️ 1
    🧵 3
    😆 1
    y
    a
    • 3
    • 3
  • h

    hawklike

    08/06/2025, 7:15 AM
    Hi 👋, I just want to ensure I understand correctly the difference between hot flow and cold flow. Even though we use State flows that are hot, operators like
    map
    ,
    filter
    or
    combine
    make hot flow cold, because their internal implementation is basically this:
    Copy code
    return flow {
        collect { value ->
            emit(transform(value))
        }
    }
    So, are the following examples correct?
    Copy code
    val stateFlowA = MutableStateFlow("A") 
    val flowA: Flow<String> = stateFlowA // Is Hot flow
    
    val stateFlowB = MutableStateFlow("B")
    val flowB: Flow<String> = stateFlowB.map { it } // Is Cold flow
    
    val flowC: Flow<String> = combine(stateFlowA, stateFlowB) { a, b -> "$a $b" } // Is Cold flow
    Thank you 🙏
    c
    s
    z
    • 4
    • 6
  • p

    Panos

    08/06/2025, 8:59 AM
    Hello, I'm using
    Copy code
    <dependency>
                <groupId>org.jetbrains.kotlinx</groupId>
                <artifactId>kotlinx-coroutines-core</artifactId>
                <version>1.10.2</version>
            </dependency>
    and in Idea I can not see
    limitedParallelism
    available for any dispatcher. I want to use
    <http://Dispatchers.IO|Dispatchers.IO>.limitedParallelism(nThreads)
    . Am I missing something fundamental?
    ✅ 1
    c
    n
    • 3
    • 4
  • e

    Edoardo Luppi

    08/07/2025, 12:51 PM
    I just stumbled upon https://youtrack.jetbrains.com/issue/KT-79957 I'm ignorant about what a multi-shot continuation is. Anyone that can enlighten my dumb brain about what it is and what's a real-world use case for it?
    k
    y
    +2
    • 5
    • 11
  • z

    Zoltan Demant

    08/07/2025, 1:53 PM
    In a library of mine, I do
    flow.flowOn(Default)
    where it makes sense; and life is good. Or so I would think, because further down the chain when I do
    flow.map { .. }
    and perform some heavy transformations on the data.. Ill eventually realize that Im doing those on the main-thread, since the backing scope is based on
    Dispatchers.Main
    . I need the results of the flow collection to be delivered on the main thread, but Id basically like all operations on it to be performed on a background one. I know that I can use withContext, specify another .flowOn, or even run the entire flow operation in a background scope - and then switch to main for the delivery.. but these seem reluctant or weird, and Id be repeating myself a lot. Is there any best practices or advice for situations like this?
    ✅ 1
    n
    z
    • 3
    • 11
  • c

    Colton Idle

    08/11/2025, 4:13 PM
    Thoughts on using runBlocking in tests instead of runTest? Seems like everything runs fine with runBlocking?
    r
    k
    +3
    • 6
    • 5
  • g

    gpopides

    08/12/2025, 9:09 PM
    I believe this issue is Dokka related but since i found it in the coroutines documentation i will first mention it here. In https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-completable-deferred/ , if you click on
    completion exception
    link, you get a 404 because the link is https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-completable-deferred/get-completion-exception-or-null.html which does not exist. if you remove the
    -completable
    from the link, it links to the correct page I had a look at the code and indeed
    getCompletionExceptionOrNull
    is part of
    Deferred
    . Clicking the KDoc link through the IDE works and you get navigated to the function. Is this a coroutines issue (the link inside KDoc) or Dokka which should generate the correct link?
    ✅ 1
    a
    o
    • 3
    • 2
  • d

    Daniel Pitts

    08/13/2025, 10:03 PM
    I have a service that returns a StateFlow for subscribers interested in a Node in a tree. I would like to close some resources when there are no subscribers. Is
    subscriptionCount
    a suitable way to track that?
    b
    • 2
    • 2
  • b

    bj0

    08/15/2025, 6:35 AM
    if I pass a
    MainScope()
    into a class that creates a ktor
    HttpClient
    to use for the lifetime of the scope, is there an idiomatic way to cleanup the client when the scope is cancelled? I can only think of launching a do-nothing coroutine that uses
    awaitCancellation
    or using
    job.invokeOnCompletion
    . I'm not sure if one of these are a good method or if there's something else?
  • r

    Rob Elliot

    08/15/2025, 9:16 AM
    Hi - we've got an app written using JVM Threads for parallelism / concurrency. We need to move one of the modules in it to coroutines. This module currently supports cancellation using
    Thread.interrupt()
    by checking
    Thread.currentThread().isInterrupted
    . Migrating that to
    currentCoroutineContext().isActive
    seemed fairly easy, but higher up the tree, and outside coroutine context, I now need to launch a coroutine and cancel it when the launching thread is interrupted, to maintain the contract. I've tried this:
    Copy code
    fun run() = runBlocking {
        val deferred = async(start = LAZY) {
          login.login()
        }
        try {
          deferred.await()
        } catch (_: InterruptedException) {
          deferred.cancel()
          deferred.await()
        }
      }
    but my tests are failing in a way that shows that the contract has changed - indeed, it looks like the InterruptedException is not caught by that catch block at all because the lambda passed to
    runBlocking
    is being run in a different thread to
    fun run()
    . But I can't get a reference to
    deferred
    outside
    runBlocking
    ! How are coroutines and threads meant to interop for cancellation?
    j
    r
    +2
    • 5
    • 10
  • b

    bj0

    08/15/2025, 10:51 PM
    When using
    flatMapLatest
    (https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/flat-map-latest.html), what happens produced (inner) flow finishes but the receiver flow does not? does it finish or wait for the next inner flow to be produced?
    z
    • 2
    • 1
  • t

    theapache64

    08/17/2025, 7:19 PM
    https://x.com/theapache64/status/1957158750566969370
    z
    • 2
    • 2
  • a

    Alex Schiff

    08/19/2025, 12:44 PM
    Would Kotlin Coroutines be a good candidate for a Publish-Subscribe method of communication inside a monolith? Would that even work?
    ✅ 1
    n
    d
    +2
    • 5
    • 17
  • 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
    +4
    • 7
    • 55
  • 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 1
    h
    • 2
    • 3