I am using withContext to transform a function into a suspending function which does not block the calling thread. For this I used https://medium.com/@elizarov/blocking-threads-suspending-coroutines-d33e11bf4761 as reference.
Now I would like to invoke this function with a timeout. For this I use withTimeout to call the function as such:
@Test
internal fun timeout() {
runBlocking {
logger.info("launching")
try {
withTimeout(1000) {
execute()
}
} catch (e: TimeoutCancellationException) {
logger.info("timed out", e)
}
}
}
private suspend fun execute() {
withContext(Dispatchers.IO) {
logger.info("sleeping")
Thread.sleep(2000)
}
}
So what I would expect is that after 1000 millis the async launched coroutine is cancelled and the TimeoutCancellationException is thrown.
But what happens is that the full 2000 millis pass and when the coroutine is completed the exception is thrown:
14:46:29.231 [main @coroutine#1] INFO b.t.c.c.CoroutineControllerTest - launching
14:46:29.250 [DefaultDispatcher-worker-1 @coroutine#1] INFO b.t.c.c.CoroutineControllerTest - sleeping
14:46:31.261 [main@coroutine#1] INFO b.t.c.c.CoroutineControllerTest - timed out kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 1000 ms at kotlinx.coroutines.TimeoutKt.TimeoutCancellationException(Timeout.kt:128) at kotlinx.coroutines.TimeoutCoroutine.run(Timeout.kt:94) at kotlinx.coroutines.EventLoopImplBase$DelayedRunnableTask.run(EventLoop.kt:307) at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.kt:116) at kotlinx.coroutines.DefaultExecutor.run(DefaultExecutor.kt:68) at java.lang.Thread.run(Thread.java:748)
Am I using something wrong?
Or perhaps this is the intended behavior? In the documentation the counter also gets to 2 which means 1500 millis have passed before the coroutine is cancelled: https://github.com/Kotlin/kotlinx.coroutines/blob/master/docs/cancellation-and-timeouts.md#timeout