-
Notifications
You must be signed in to change notification settings - Fork 1.8k
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
withTimeoutOrNull returns null even when it did not timeout itself #67
Comments
Modifiying
Fixes the issue for me, but I’m not sure I fully understand the semantics of yield. Is this logically correct? I’m worried that the call to |
Yield just reschedules the task and checks for cancellation. That is why your particular problem is fixed. It does not address the core issue itself. The root questions here is what semantics should |
I'm personally inclined to rule that |
And same goes for |
There is no problem with |
I see. I originally encountered this problem because I wasn't aware of
I understand they might be different use cases, but from a user point of view this way of doing things also looks pretty innocent at first. Hard to see that you're shooting yourself in the foot here. I wonder if there's a way to make it harder for users to do stupid things like this. |
Another test program. I'm surprised that both import kotlinx.coroutines.experimental.*
import java.util.concurrent.TimeUnit
val S = TimeUnit.SECONDS
suspend fun <T> withTimeoutOrNull2(time: Long, unit: TimeUnit, block: suspend () -> T): T? = try {
withTimeout(time, unit) {
block()
}
} catch (_: CancellationException) { null }
suspend fun nested1(outer: Long, inner: Long, delayed: Long) =
withTimeoutOrNull(outer, S) {
withTimeoutOrNull(inner, S) {
delay(delayed, S)
"delay"
} ?: "inner timeout"
} ?: "outer timeout"
suspend fun nested2(outer: Long, inner: Long, delayed: Long) =
withTimeoutOrNull2(outer, S) {
withTimeoutOrNull2(inner, S) {
delay(delayed, S)
"delay"
} ?: "inner timeout"
} ?: "outer timeout"
suspend fun test(outer: Long, inner: Long, delayed: Long) {
val result1 = nested1(outer, inner, delayed)
val result2 = nested2(outer, inner, delayed)
println("test($outer, $inner, $delayed) = { 1: $result1, 2: $result2 }")
}
fun main(args: Array<String>) = runBlocking {
test(1, 2, 3)
test(1, 3, 2)
test(2, 1, 3)
test(2, 3, 1)
test(3, 1, 2)
test(3, 2, 1)
} |
For the other cases:
For reference, the output of the test above is:
|
FYI, here's my workaround to the problem:
The call
And:
This gives the correct results:
|
Fixed in |
Copied from message by @gregschlom at public slack:
Hey guys. I have an issue with nested withTimeouts. Here’s some example code:
The problem here is that we have two nested
withTimeout
callsThe 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 timeoutTherefore it returns null either way
The text was updated successfully, but these errors were encountered: