Joffrey
05/19/2022, 12:44 PMsuspend fun main is considered inactive?
suspend fun main() {
println(currentCoroutineContext().isActive) // prints false
}
https://pl.kotl.in/sVFnLz9mMephemient
05/19/2022, 1:04 PMsuspend fun main uses a super simple dispatcher instead of depending on kotlinx.coroutines. since it doesn't have a Job, it's !isActive. https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/jvm/src/kotlin/coroutines/jvm/internal/RunSuspend.ktephemient
05/19/2022, 1:06 PMsuspend fun main() = coroutineScpoe {
println(isActive)
}
produces true because it goes into the kotlinx.coroutines world, but without that, it doesn'tJoffrey
05/19/2022, 1:12 PMcoroutineContext.isActive was from kotlinx.coroutines, unlike coroutineContext.
Yeah I understand the other options of using coroutineScope or removing suspend and using runBlocking.
That said, it makes using suspend fun main pretty awkward if you use things that are aware of structured concurrency without wrapping them in coroutines first. I wonder if production code should use it at all, now.ephemient
05/19/2022, 1:14 PMJoffrey
05/19/2022, 1:16 PMsuspend fun from a library that relies on while(coroutineContext.isActive) . I didn't need to launch a coroutine to call that function from suspend fun main.Joffrey
05/19/2022, 1:18 PMsuspend fun directly from suspend fun main without coroutine, or the fact that the lib function was using while(isActive) 🤔ephemient
05/19/2022, 1:19 PMwhile (currentCoroutineContext().isActive) seems like a bug to begin with. it'll fail in anything else that uses (non-kotlinx.)coroutines too, e.g. sequence() buildersJoffrey
05/19/2022, 1:22 PMsequence builders have restricted suspend access via special annotations, though, exactly to avoid this kind of problemsephemient
05/19/2022, 1:25 PMJoffrey
05/19/2022, 1:32 PMwhile(isActive) in the function in question is just superstition I believe, because the loop contains suspending calls anyway so it shouldn't be necessary. And even if that were not the case, we could also introduce yield() calls in the loop and it would have the same effect of detecting cancellation. Still begs the question, should while(isActive) be considered an anti-pattern in general?ephemient
05/19/2022, 1:35 PMwhile (isActive) could be useful if you're looping around non-suspending code, but it should be known to come from a CoroutineScope - from a function local coroutineScope {} if it's not given an external scope. a CoroutineContext is usually not something you'd be touchingephemient
05/19/2022, 1:36 PMyield() to suspend) then it's probably not useful to use isActive, I thinkJoffrey
05/19/2022, 1:41 PMisActive is defined on the coroutineContext itself, even though it doesn't have any meaning when there is no Job in the context. I think defining it at this level anyway with the value false is just a footgun.Joffrey
05/19/2022, 1:43 PMcoroutineScope would work, it is painfully not obvious why it would be there if no coroutines are launched in it. The connection between the presence of coroutineScope and the usage of coroutineContext.isActive is not shown by the compiler, and I think seeing such code I would be the first person to carelessly remove the "useless" coroutineScope wrapperephemient
05/19/2022, 1:43 PMCoroutineScope, but I agree the one on CoroutineContext is a likely footgunJoffrey
05/19/2022, 1:43 PMCoroutineScope would solve the problem I was mentioningephemient
05/19/2022, 1:44 PMcoroutineScope from coroutineScope { while (isActive) { ... } } will break compilationAtul Gupta
08/18/2024, 9:04 PM1.9.25 it starts to print true (before 1.9.25 it is still giving false.) Is there any change to this behaviour?Joffrey
08/18/2024, 9:08 PM