Hong Phuc
08/30/2025, 4:44 AMMarking a functiongives 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 aresuspendandsuspendCoroutine(). You will not often use these. They are most commonly used to convert non-coroutine APIs into suspend functions.suspendCancellableCoroutine()
Some of the commonly used functions that indirectly suspend a coroutine areI found it in this Stackoverflow post.,withContext(),delay()andJob.join().Deferred.await()
Tian Tian098
09/05/2025, 6:36 PMflow { /* 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.
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
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?David Breneisen
09/06/2025, 10:13 AMIrsath Kareem
09/08/2025, 10:20 AM// 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)
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)ursus
09/11/2025, 4:13 PMprivate 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?Dontsu
09/13/2025, 2:25 AMdelay() 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.
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")
}
}xenomachina
09/13/2025, 3:38 AMmessages. However, IntelliJ is saying "'messages was optimised out". This is despite the fact that my code uses this the variable after the breakpoint.
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?Abhimanyu
09/16/2025, 3:48 AMColton Idle
09/16/2025, 11:00 PMclass MyCoolHandler{
var mContinuation: Continuation<Foo>? = null
suspend fun waitingForFoo(): Foo = suspendCoroutine { continuation ->
// code
mContinuation = continuation
}
// some other class functions
}Alex Styl
09/18/2025, 9:46 AMmutableXOf 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?ursus
09/18/2025, 9:17 PMcoroutineScope { .. } length, or is it okay to have ot extend to the full function body?
Whats more idiomatic?Joshua Hansen
09/18/2025, 9:27 PMwithContext for every switch between UI and background?
Currently I have:
suspend fun openView(path: Path): MyView {
// Load data
return withContext(Dispatchers.Swing) {
// Create UI View
}
}Joshua Hansen
09/19/2025, 7:22 PMval 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()
}Hong Phuc
09/22/2025, 2:15 AMRob Elliot
09/23/2025, 11:17 AMsealed 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()?Tian Tian098
09/24/2025, 3:52 AMval 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.Jonas
09/24/2025, 12:48 PMFlow using callbackFlow , do I have to call close() after trySend(...) when the call back only emits once?Julius Babies
09/27/2025, 7:20 PMArtyom Gornostayev
09/29/2025, 10:03 AMkotlin-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. :)CLOVIS
10/01/2025, 12:51 PMreactormonk
10/09/2025, 12:36 PMreactormonk
10/15/2025, 4:16 PMfirst() doesn't get cancelled by the timeoutMario Andhika
10/17/2025, 7:04 AMobject MyObject {
var x = 1
init {
GlobalScope.launch {
x++
}
}
}
suspend fun main() = coroutineScope {
println(MyClass.x.toString()) // output: 1
delay(100L)
println(MyClass.x.toString()) // output: 2
}
How to make MyClass.x.toString() print 2 without needing to have a delay statement? How should I change the init block?Peter
10/20/2025, 1:48 AMCLOVIS
10/20/2025, 6:13 PMDebugProbes.install() is very slow! Here, it takes between ~1.5s and ~3s depending on the run, and it's called once for each Gradle moduleursus
10/22/2025, 12:21 AMMutableSharedFlow (that acts as a trigger to refresh stuff), that has a default value (so syncs get triggered right away on start)?
I find manually throwing in `trigger.emit(Unit)`after everyone is subscriber a bit awkwards
Unless there is an API I'm not aware of, probably the best would be to have own subclass right? Like this maybe?
class TriggerFlow : Flow<Unit> {
private val _trigger = MutableSharedFlow<Unit>(
replay = 1
)
init {
_trigger.tryEmit(Unit)
}
suspend fun trigger() {
_trigger.emit(Unit)
}
override suspend fun collect(collector: FlowCollector<Unit>) {
_trigger.collect(collector)
}
}
How does this look? Is the tryEmit in init cool?Lukas K-G
10/22/2025, 1:35 PMinternal fun ScheduledAdItem.adItemStatusAsFlow() = callbackFlow {
trySendBlocking(adItemStatus)
val statusListener = AdItemStatusListener { _, status -> trySendBlocking(status) }
addStatusListener(statusListener)
awaitClose { removeStatusListener(statusListener) }
}
We figured that this is likely due to the trySendBlocking which does a runBlocking.
We then pivoted to the following:
internal fun ScheduledAdItem.adItemStatusAsFlow() = callbackFlow {
send(adItemStatus)
val statusListener = AdItemStatusListener { _, status -> launch { send(status) }}
addStatusListener(statusListener)
awaitClose { removeStatusListener(statusListener) }
}
Which we then figured that it might not guarantee the order of events if run on a coroutine dispatcher with multiple threads.
What would be the recommended way to implement a cancellation cooperative callback flow with guaranteed event order?
Thanks in advance!Alex Styl
10/24/2025, 3:17 AMdelay() for some days and then continue the coroutine)Winson Chiu
10/27/2025, 8:12 PMrunTest workaround for withTimeout using withContext(Dispatchers.Default.limitedParallelism(1)), but is there a workaround for Flow.timeout? I can flowOn, but I'd rather not force my entire Flow to a specific dispatcher if possible.Bernhard
10/29/2025, 1:57 PM