Open
Description
If withTimeout
wraps a blocking job, it does not detect a timeout in conjunction with newSingleThreadContext()
. Timeout detection works as expected with other dispatcher flavors:
import kotlinx.coroutines.* // ktlint-disable no-wildcard-imports
import java.util.concurrent.Executors
@OptIn(ExperimentalCoroutinesApi::class, DelicateCoroutinesApi::class)
fun main(): Unit = runBlocking {
listOf(
Triple("newSingleThreadExecutor", { Executors.newSingleThreadExecutor().asCoroutineDispatcher() }, true),
Triple("newSingleThreadContext", { newSingleThreadContext("single") }, true),
Triple("newFixedThreadPoolContext(2)", { newFixedThreadPoolContext(2, "double") }, true),
Triple("IO.limitedParallelism(1)", { Dispatchers.IO.limitedParallelism(1) }, false),
Triple("IO.limitedParallelism(2)", { Dispatchers.IO.limitedParallelism(2) }, false)
).forEach { (name, dispatcher, needsClosing) ->
print("$name: ")
val dispatcher = dispatcher()
try {
withContext(dispatcher) {
try {
withTimeout(1000) {
launch {
Thread.sleep(2000)
// delay(2000)
}
}
println("no timeout detected")
} catch (t: Throwable) {
println("$t")
}
}
} finally {
if (needsClosing) (dispatcher as ExecutorCoroutineDispatcher).close()
}
}
}
produces:
newSingleThreadExecutor: kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 1000 ms
newSingleThreadContext: no timeout detected
newFixedThreadPoolContext(2): kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 1000 ms
IO.limitedParallelism(1): kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 1000 ms
IO.limitedParallelism(2): kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 1000 ms
Version: kotlinx-coroutines-core:1.7.3
Effects observed here first: kotest/kotest#3672