Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

szeiger
Copy link
Contributor

@szeiger szeiger commented Apr 24, 2023

Previously, an InterruptedException might cause a Future 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.

  • 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.

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.
@scala-jenkins scala-jenkins added this to the 2.12.18 milestone Apr 24, 2023
@SethTisue SethTisue added the library:concurrent Changes to the concurrency support in stdlib label Apr 24, 2023
@SethTisue SethTisue changed the title InterruptedException handling for Futures [backport] InterruptedException handling for Futures Apr 24, 2023
@@ -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)
Copy link
Member

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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?

Copy link
Member

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()"

summon[@viktorklang]?

Copy link
Contributor Author

@szeiger szeiger Jun 2, 2023

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).

@SethTisue SethTisue added the release-notes worth highlighting in next release notes label May 1, 2023
@SethTisue SethTisue modified the milestones: 2.12.18, 2.12.19 May 1, 2023
Copy link
Member

@lrytz lrytz left a 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...

@SethTisue SethTisue merged commit c3cd9a7 into scala:2.12.x Jan 18, 2024
@SethTisue
Copy link
Member

SethTisue commented Jan 18, 2024

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!

@som-snytt
Copy link
Contributor

Worst case, any commit on 2.12 helps get people off 2.12.

@SethTisue SethTisue changed the title [backport] InterruptedException handling for Futures [backport] Improved InterruptedException handling for Futures Feb 6, 2024
hamzaremmal pushed a commit to hamzaremmal/scala3 that referenced this pull request May 2, 2025
[backport] InterruptedException handling for Futures
hamzaremmal pushed a commit to scala/scala3 that referenced this pull request May 7, 2025
[backport] InterruptedException handling for Futures
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
library:concurrent Changes to the concurrency support in stdlib release-notes worth highlighting in next release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants