-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Should runInterruptible
throw InterruptedIOException
as CancellationException
?
#3551
Comments
I'm not sure. square/okhttp#3945 says that OkHttp will throw |
@JakeWharton care to comment? |
@yschimke maintains OkHttp |
I'll take a look, and happy to fix specific issues which are obviously not correct. General context... I'm wary about promising too much for OkHttp here. Our draft north star for cancellation is this square/okhttp#7185, but its still advising against interrupts because they are likely bad for performance of pooled connections. In truth there are a bunch of edge cases that happen at the moment during new stream creation, that can manifest as bugs under interrupts. So double wary here. Post response is probably fine. |
Making this change above, and swallowing timeouts accidentally via runInterruptible does look problematic. Since both Okio (via non-clearing Aternatively, looking into this for okhttp change, I suspect it's not just okhttp, but also okio that would need to change here. okio - timeout and cancellation as InterruptedIOException okhttp - test confirming timeout as InterruptedIOException So @swankjesse for Okio and OkHttp... I suspect a part of reason OkHttp deliberately throws InterruptedIOException, is that internally the code cleanly handles IOExceptions but not runtime exceptions. We also don't want to do any other IO after this via retries, so retaining the interrupt status up to caller code is a safe default. Technically I think Okio is breaking the contract of InterruptedIOException, but arguable. Because of this my suggestion in the first line of checking the status, appears okio/okhttp specific, it may not apply to any other libraries.
|
For APIs written to support non-coroutines users, CancellationException is a non-starter. I recommend changing Note: I previously responded as if this was an issue reported against OkHttp. My bad! |
We would need to look at how
In this case, where "1" takes effect immediately and the error indicates a timeout, this could be fine: we all could just pretend that |
So, I've looked into it. Seems like people really do use The docs state:
However, https://docs.oracle.com/javase/7/docs/api/java/net/SocketTimeoutException.html does not seem to behave this way: val url = URL("https://www.google.com")
Thread.currentThread().interrupt() // <-------------------------- no effect
val conn: HttpURLConnection = url.openConnection() as HttpURLConnection
conn.connectTimeout = 1000 // remove the zeros to observe the exception
try {
println((conn.content as InputStream).readAllBytes().toString(Charsets.UTF_8))
} catch (e: InterruptedIOException) {
println(Thread.currentThread().isInterrupted)
} I see some HTML being printed, so this just… ignores that the thread was interrupted. Maybe I'm missing something? So, we have three interpretations of
I'd say, with all this, we should never swallow an |
We preserve the interrupted state in OkHttp so that catching an IOException doesn’t lose information.
In this sample, if the thread is interrupted we shouldn’t just fall back to the secondary server. |
Good to know, thanks, that's a solid reason! Though I don't see any downsides to just throwing In any case, this is irrelevant to the discussion, which is about whether or not we, the coroutines library, should catch |
@dkhalanskyjb so catching InterruptedIoException and throwing InterruptedException so runInterruptible kicks in, is bad? |
If you know you're using it with OkHttp, by all means, do this, just don't forget to check the interrupt flag. We are a general-purpose library and can't write code specifically tailored to OkHttp at the expense of other use cases, but in your own code, you can do whatever you want! |
@dkhalanskyjb if we can definitively state that some of these are wrong, we can definitely look at changing this in OkHttp 5. As square/okhttp#7185 shows, we'd like to be good interrupt citizens. |
I don't think we can definitely state anything conclusive about |
When used with retrofit/okhttp/okio stack, reading and writing bytes becomes
However the read/writes become blocking and non cancellable. Fortunatelly okio checks for java thread interrupts, so
runInterruptible
can be usedHowever, okio throws
java.io.InterruptedIOException
, which therunInterruptible
doesn't then repackage asCancellationException
Should be repackage this exception as well?
The text was updated successfully, but these errors were encountered: