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

Fork join execution context loses fatal exceptions #7029

Closed
scabug opened this Issue Jan 27, 2013 · 8 comments

Comments

Projects
None yet
2 participants
@scabug
Copy link

scabug commented Jan 27, 2013

The fork join execution context loses fatal exceptions. It should allow them to be handled by the threads uncaught exception handler, so that they can be logged. But it doesn't, they get lost, not reported anywhere. Here is an example in the repl:

scala> import scala.concurrent._
import scala.concurrent._

scala> val ec = scala.concurrent.ExecutionContext.global
ec: scala.concurrent.ExecutionContextExecutor = scala.concurrent.impl.ExecutionContextImpl@4a640180

scala> val f = Future[Unit](throw new NotImplementedError())(ec)
f: scala.concurrent.Future[Unit] = scala.concurrent.impl.Promise$DefaultPromise@3ec9e1f9

Nothing happens. What I expected is for my NotImplementedError to be at least handled by the uncaught exception handler, and logged. Now, I know the uncaught exception handler is there and working:

scala> val f = Future[Unit](Thread.currentThread.getUncaughtExceptionHandler.uncaughtException(Thread.currentThread, new NotImplementedError()))(ec)
f: scala.concurrent.Future[Unit] = scala.concurrent.impl.Promise$DefaultPromise@4aac53a8
Exception in thread "ForkJoinPool-1-worker-1" scala.NotImplementedError: an implementation is missing
	at $line53.$read$$iw$$iw$$iw$$iw$$anonfun$1.apply$mcV$sp(<console>:11)
	at $line53.$read$$iw$$iw$$iw$$iw$$anonfun$1.apply(<console>:11)
	at $line53.$read$$iw$$iw$$iw$$iw$$anonfun$1.apply(<console>:11)
	at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
	at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
	at scala.concurrent.forkjoin.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1417)
	at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:262)
	at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:975)
	at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1478)
	at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:104)

And if I use a different execution context, such as a Java executor, it works as expected:

scala> val es = java.util.concurrent.Executors.newSingleThreadExecutor
es: java.util.concurrent.ExecutorService = java.util.concurrent.Executors$FinalizableDelegatedExecutorService@10cd508f

scala> val ec = ExecutionContext.fromExecutorService(es)
ec: scala.concurrent.ExecutionContextExecutorService = scala.concurrent.impl.ExecutionContextImpl$$anon$1@11e9c5a7

scala> val f = Future[Unit](throw new NotImplementedError())(ec)
f: scala.concurrent.Future[Unit] = scala.concurrent.impl.Promise$DefaultPromise@7309eabd
Exception in thread "pool-1-thread-1" scala.NotImplementedError: an implementation is missing

 	at $line69.$read$$iw$$iw$$iw$$iw$$anonfun$1.apply(<console>:12)
	at $line69.$read$$iw$$iw$$iw$$iw$$anonfun$1.apply(<console>:12)
	at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
	at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
	at java.lang.Thread.run(Thread.java:722)
@scabug

This comment has been minimized.

Copy link
Author

scabug commented Jan 27, 2013

Imported From: https://issues.scala-lang.org/browse/SI-7029?orig=1
Reporter: @jroper
Affected Versions: 2.10.0

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Jan 28, 2013

@retronym said:
Philipp: could you take a look of this ahead of 2.10.1?

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Jan 29, 2013

@jroper said:
Apparently Viktor has been talking to Doug Lea about getting a fix for this, since the problem is in the Java forkjoin library.

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Jan 29, 2013

@viktorklang said:
I've managed to work around it for Akka, but to fix the global EC in scala.concurrent, we need to do something similar to this: https://github.com/akka/akka/pull/1085/files
However, there's a bigger topic at hand here, the one whether NotImplementedError, InterruptedException and ControlThrowable are to be considered fatal or not.

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Jan 30, 2013

@viktorklang said (edited on Jan 31, 2013 3:30:17 PM UTC):
Fixed here: viktorklang/scala@b673248

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Jan 31, 2013

@phaller said:
I've just reviewed Viktor's fix. I think we should open a new self-contained pull request, though.

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Jan 31, 2013

@viktorklang said:
Yeah, that's fine, just cherry-pick my commit above. This should go in for both 2.10.x and 2.11 IMO

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Feb 1, 2013

@phaller said:
New PR: scala/scala#2044

@scabug scabug closed this Feb 2, 2013

@scabug scabug added this to the 2.10.1 milestone Apr 7, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment