Closed
Description
Copied from message by @gregschlom at public slack:
Hey guys. I have an issue with nested withTimeouts. Here’s some example code:
val channel = Channel<Int>()
// this blocks indefinitely if the channel is empty
suspend fun nexValue(): Int {
println("Waiting for next value ")
return channel.receive()
}
// same as nextValue(), but returns null after the timeout expires
suspend fun nextValueWithTimout(t: Long): Int? {
return withTimeoutOrNull(t) { nexValue() }
}
suspend fun longOperation() {
println("Starting long operation")
while (true) {
val v = nextValueWithTimout(1000)
if (v == null) {
println("timed out")
// Nothing was received in our channel.
// Do some other work while we wait for the value to arrive. Maybe we want to re-try sending
// a message to our value producer for example
}
if (v == 42) return
}
}
@Test
fun main() = runBlocking {
// This never returns. Instead we get stuck in an infinite loop in the while() above
withTimeout(5000) {
longOperation()
}
}
The problem here is that we have two nested withTimeout
calls
The code is generally suspended inside nextValue(). When the outer timeout fires (the one in the main function), there’s no way for the code in nextValueWithTimout
to know whether it was it’s own timeout that fired or some other timeout
Therefore it returns null either way
Metadata
Metadata
Assignees
Labels
No labels