-
Notifications
You must be signed in to change notification settings - Fork 3.1k
[backport] Improved InterruptedException
handling for Future
s
#10379
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
Conversation
This fixes scala/bug#8938 for Scala 2.12 in a way that is compatible with the behavior of 2.13 introduced in 05c2b43. - Relevant test suite parts taken verbatim from the 2.13 version, with one exception: I did not modify the messages of wrapped exceptions, therefore PromiseTests expects the name "Boxed InterruptedException" (as used in `Promise.resolver` in 2.12) instead of "Boxed Exception". - The actual implementation is not based on 2.13, which was a major rewrite that cannot be applied cleanly to 2.12 and is not fully source or binary compatible. Instead I implemented a strategic fix in as simple a way as possible.
@@ -28,9 +28,15 @@ private[concurrent] trait Promise[T] extends scala.concurrent.Promise[T] with sc | |||
import scala.concurrent.Future | |||
import scala.concurrent.impl.Promise.DefaultPromise | |||
|
|||
private[this] final def wrapFailure(t: Throwable): Throwable = { | |||
if (NonFatal(t)) t | |||
else if (t.isInstanceOf[InterruptedException]) new ExecutionException("Boxed InterruptedException", t) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems 2.13 also calls Thread.currentThread.interrupt()
, should that be done here too?
#6610 says "Makes Futures correctly handle Thread.interrupt", I don't know what that entails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new extended example shows receiving the ExecutionException; on 2.12 it currently throws up the stack; with this fix, the world is right again. I just waffled on whether to re-interrupt in this fix for vulpix where process.waitFor
is interrupted by pool.shutdown
. It should interrupt (after retrying its work) in case subsequent work happens on the worker thread, even though one might assume that one is the last "client" of the thread. So I'd vote for interrupting the current (worker) thread.
I've forgotten the brouhaha over running side effects on the "current" thread; is there such an executor? But maybe it is irrelevant whether we know who created the current thread. If we caught the exception, we should set the interrupt status.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really understand that part and it's not obvious how to adapt it to the 2.12 design which is completely different. Since the new test suite passes with this version, it's obviously untested (and unspecified). Is the idea to always interrupt the current thread if a Promise was completed with a boxed InterruptedException?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the idea to always interrupt the current thread if a Promise was completed with a boxed InterruptedException?
That's how the 2.13 code reads.
Googlin' I find many places that say "if you catch an InterruptedException
, you should call Thread.currentThread.interrupt()
"
- https://stackoverflow.com/questions/20934817/why-thread-currentthread-interrupt-be-called
- https://stackoverflow.com/questions/4906799/why-invoke-thread-currentthread-interrupt-in-a-catch-interruptexception-block
- https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
summon[@viktorklang]?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to add the same interrupt handling as in 2.13 (i.e. not always interrupting when InterruptedException
was caught but only when the promise was successfully completed with this exception).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. More reviews welcome...
It does make me nervous to tinker with this at this late stage in 2.12 development. But we shouldn't be unreasonably scared, given that the bug this addresses is rather serious. Thank you, Stefan. And, fingers crossed! |
Worst case, any commit on 2.12 helps get people off 2.12. |
InterruptedException
handling for Future
s
[backport] InterruptedException handling for Futures
[backport] InterruptedException handling for Futures
Previously, an
InterruptedException
might cause aFuture
to never complete. Now the future will fail.This fixes scala/bug#8938 for Scala 2.12 in a way that is compatible with the behavior of 2.13 introduced in 05c2b43.
Promise.resolver
in 2.12) instead of "Boxed Exception".