Leftover callbacks on execution context shutdown

889 views
Skip to first unread message

Som Snytt

unread,
Jan 31, 2013, 3:08:19 AM1/31/13
to scala-internals

ExecutionService.shutdown allows previously submitted tasks to complete.

However, I suppose that if I shutdown an ExecutionContext, the onCompletes of previously submitted futures won't get run.  Ought they?

Maybe there could be a policy setting to decide what to do with them.

(One option would be to run on the current thread if the target executor.isShutdown.  Or perhaps only if the target is the current executor.)

(Alternatively, the EC could have a shutdown state that gets propagated to the underlying ES only after callbacks have run.  Just thinking aloud.)

My use case is that tasks on A create tasks on B, so once all futures are created, it's convenient to A.shutdown without any book-keeping.

Footnote, error from simple test is clear:

Exception in thread "pool-1-thread-1" java.util.concurrent.RejectedExecutionException: Task scala.concurrent.impl.CallbackRunnable@f1bb79c rejected from java.util.concurrent.ThreadPoolExecutor@64b36a83[Shutting down, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0]
        at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2013)
        at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:816)
        at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1337)
        at scala.concurrent.impl.ExecutionContextImpl$$anon$1.execute(ExecutionContextImpl.scala:118)
        at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:37)
        at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:133)
        at scala.concurrent.Promise$class.complete(Promise.scala:55)
        at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:58)
        at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:23)
        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)


This other error is more obscure:

java.lang.IllegalStateException: Promise already completed.
        at scala.concurrent.Promise$class.complete(Promise.scala:55)
        at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:58)
        at scala.concurrent.Promise$class.failure(Promise.scala:107)
        at scala.concurrent.impl.Promise$DefaultPromise.failure(Promise.scala:58)
        at scala.concurrent.Future$$anonfun$map$1.apply(Future.scala:257)
        at scala.concurrent.Future$$anonfun$map$1.apply(Future.scala:249)
        at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:29)
        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)


√iktor Ҡlang

unread,
Jan 31, 2013, 4:29:49 AM1/31/13
to scala-i...@googlegroups.com
On Thu, Jan 31, 2013 at 9:08 AM, Som Snytt <som....@gmail.com> wrote:

ExecutionService.shutdown allows previously submitted tasks to complete.

However, I suppose that if I shutdown an ExecutionContext, the onCompletes of previously submitted futures won't get run.  Ought they?

That will never work, not only can-and-usually-do callbacks yield more callbacks, but they also run on other ExecutionContexts, which in turn may schedule things to run on the shut down ExecutorService.
 

Maybe there could be a policy setting to decide what to do with them. 

(One option would be to run on the current thread if the target executor.isShutdown.  Or perhaps only if the target is the current executor.)

Have you tried, and what results did you get?
 

(Alternatively, the EC could have a shutdown state that gets propagated to the underlying ES only after callbacks have run.  Just thinking aloud.)

Sounds interesting, would love to see a proof of concept that passes the test suite. However, it is a conscious decision not to have a shutdown method on ExecutionContext.
Please open a ticket in the scala tracker and I'll see if that can be hardened a bit more.

Cheers,
 



--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Viktor Klang
Director of Engineering

Typesafe - The software stack for applications that scale
Twitter: @viktorklang

√iktor Ҡlang

unread,
Jan 31, 2013, 5:47:20 AM1/31/13
to scala-i...@googlegroups.com
Please verify.

Cheers,
 

Cheers,
 



--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Viktor Klang
Director of Engineering

Typesafe - The software stack for applications that scale
Twitter: @viktorklang

Som Snytt

unread,
Jan 31, 2013, 12:11:56 PM1/31/13
to scala-i...@googlegroups.com
On Thu, Jan 31, 2013 at 2:47 AM, √iktor Ҡlang <viktor...@gmail.com> wrote:

 

(Alternatively, the EC could have a shutdown state that gets propagated to the underlying ES only after callbacks have run.  Just thinking aloud.)

Sounds interesting, would love to see a proof of concept that passes the test suite. However, it is a conscious decision not to have a shutdown method on ExecutionContext.

Thanks for the reply.  I'll see what I come up with.

Also, thanks for the drumbeat on the evils of blocking.  It's so true.

I'll check out the exception handling; I started looking at it because of the other thread about exceptions in futures.

√iktor Ҡlang

unread,
Jan 31, 2013, 12:57:13 PM1/31/13
to scala-i...@googlegroups.com
Happy hAkking :-)


--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 
Reply all
Reply to author
Forward
0 new messages