[concurrency-interest] AsyncCompose is a blocking operation?

James Roper james at typesafe.com
Tue Sep 22 22:51:07 EDT 2015


Hi,

So firstly the problem that triggers this, I'm seeing deadlocks in
CompletableFutures when you try to use asyncCompose in combination with a
trampoline executor.

For those unaware, a trampoline executor is one that runs submitted tasks
on the current thread, however it attempts to solve stack overflow errors
caused when tasks submit big chains of nested tasks to the executor, by
using a thread local to queue these tasks up to be executed sequentially
when nested submission happens, rather than immediately.

Now the problem appears to be that in certain circumstances
CompletableFuture will block on another CompletableFuture, for example, it
blocks until the result of a CompletableFuture returned by the callback
passed to thenCompose is redeemed.  This is of course dangerous, since if
this returned future is dependent on the same executor that the current
thread is blocking in, it might deadlock due to thread exhaustion.
CompletableFuture does try to handle this, but its handling seems to assume
that the only executor this could happen on is a ForkJoinPool, and it
addresses it by temporarily increasing the allowed parallelism of that
pool.  However, that approach is tied to ForkJoinPools, and does not work
for any other type of executor, in particular trampoline executors, which
don't support any parallelism, but require all operations to be non
blocking.  So I think there are some bad assumptions about the executors
being used here.  If CompletableFuture can only work with ForkJoinPool,
then it should only accept ForkJoinPool in its API.  Since it accepts
Executor, it must work with all executors.

But, this brings us to AsyncCompose being blocking.  It seems that
AsyncCompose will always block on the returned CompletableFuture.  Am I
correct, or have I misread the code? Why is this?  Shouldn't AsyncCompose
rather attach a callback to the returned CompletableFuture, and redeem its
associated CompletableFuture when that callback is executed?  Doesn't
blocking here defeat the whole purpose of asynchronous programming?

Regards,

James

-- 
*James Roper*
*Software Engineer*

Typesafe <http://typesafe.com/> – Build reactive apps!
Twitter: @jroper <https://twitter.com/jroper>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20150923/580e625f/attachment.html>


More information about the Concurrency-interest mailing list