Alexander Maryanovsky
06/03/2023, 8:59 AMDelay.scheduleResumeAfterDelay
such that
1. The continuation runs in a certain CoroutineScope
2. I am able to query whether there are any continuations waiting to be resumed.
Currently we have something that looks roughly like this:
val delayedTasks = mutableSetOf<Runnable>()
override fun scheduleResumeAfterDelay(timeMillis: Long, continuation: CancellableContinuation<Unit>) {
val block = Runnable { continuation.resume(Unit, null) }
delayedTasks.add(block)
scope.launch {
kotlinx.coroutines.delay(timeMillis)
delayedTasks.remove(block)
block.run()
}
}
but if someone launches a coroutine that delays (say for a long time) and then cancels the Job, this will not be notified that the coroutine was cancelled and will be stuck in delay
until timeMillis
runs out.
How do I do this correctly?Alexander Maryanovsky
06/03/2023, 9:10 AMoverride fun scheduleResumeAfterDelay(timeMillis: Long, continuation: CancellableContinuation<Unit>) {
val block = Runnable { continuation.resume(Unit, null) }
delayedTasks.add(block)
val job = scope.launch {
try {
kotlinx.coroutines.delay(timeMillis)
} finally {
delayedTasks.remove(block)
block.run()
}
}
continuation.invokeOnCancellation {
job.cancel()
}
}