Jobs and coroutines are typically expected to complete quickly after being cancelled. Is there a built-in way to track that they do, essentially a kind of runtime assertion? I believe this would help me find leaks.
I can do this on an individual Job/coroutine basis by adding some tracking code at the Job creation site, but I am looking for an easy way to do it at a broader level, like the runtime or Dispatcher.
z
Zach Klippenstein (he/him) [MOD]
06/07/2024, 11:26 PM
cancelAndJoin?
u
Uli Bubenheimer
06/07/2024, 11:42 PM
Umm, no
Uli Bubenheimer
06/08/2024, 12:30 AM
Here's a complete example. job1 is cancelled by its parent, but never completes, because it does not suspend. I can detect this situation with something like the second launch. However, I have to use a check like this individually in every possible place where this could happen to detect it. I am looking for a hook to check for this situation automatically. I imagine I could likely do it with a custom Dispatcher, but that's not really feasible. Is there any built-in debug-like thingy that could detect this, or a Dispatcher or runtime hook, or maybe someone created a custom solution?
Copy code
coroutineScope {
val job1 = launch(<http://Dispatchers.IO|Dispatchers.IO>) {
// bad job: runs for a long time, and fails to suspend
while (true) {}
}
launch {
// check that job1 completes soon after parent cancellation
try {
awaitCancellation()
} finally {
GlobalScope.launch {
delay(5.seconds)
if (!job1.isCompleted) println("Not completing")
}
}
}
// Wait a bit, then cancel our parent scope
delay(5.seconds)
this.cancel()
}
Uli Bubenheimer
06/08/2024, 12:47 AM
cancelAndJoin()
does not help, because in general there are many ways that job1 could end up getting cancelled.
Uli Bubenheimer
06/08/2024, 12:47 AM
I want to detect that job1 is leaking, like a LeakCanary for coroutines