[concurrency-interest] We need to add blocking methods to CompletionStage!

Benjamin Manes ben.manes at gmail.com
Wed Sep 21 21:25:58 UTC 2016

My limited understanding is that the original API was
only CompletableFuture and that CompletionStage introduced as a compromise.
It did not appear to be an attempt to strictly follow an
interface-implementation separation, e.g. collections. As you said
may throw an UOE, which means some use-cases can't rely on CompletionState
which limits its usefulness. In my case that would be an AsyncLoadingCache
with a synchronous LoadingCache view. I think having to code that the
resulting implementation would be worse if it called toCompletableFuture,
caught the exception, and then adapted as you said.

When the new future class was introduced it was stated,

"In other words, we (j.u.c) are not now in a position to dictate a common
interface for all SettableFuture, FutureValue, Promise, ListenableFuture,
etc like APIs. And as we've seen, different audiences want/need different
subsets of this API exposed as interfaces for their usages, and are in any
case unlikely to want change all their existing interfaces. However, what
we can do is provide a common underlying implementation that is as fast,
scalable, space-conserving, carefully-specified, and reliable as possible.
It should then be easy and attractive for others creating or reworking
higher-level APIs to relay all functionality to the CompletableFuture
implementation."  - Doug Lea, '12

I've gradually come to terms using CF as part of an API and haven't
experienced a downside yet.

On Wed, Sep 21, 2016 at 1:43 PM, Martin Buchholz <martinrb at google.com>

> (Sorry to re-open this discussion)
> The separation of a read-only CompletionStage from CompletableFuture is
> great.  I'm a fan of the scala style Promise/Future split as described in
> http://docs.scala-lang.org/overviews/core/futures.html, but: we need to
> re-add (safe, read-only) blocking methods like join.  Java is not Node.js,
> where there are no threads but there is a universal event loop.  Java
> programmers are used to Future, where the *only* way to use a future's
> value is to block waiting for it.  The existing CompletionStage methods are
> a better scaling alternative to blocking all the time, but blocking is
> almost always eventually necessary in Java.  For example, junit test
> methods that start any asynchronous computation need to block until the
> computation is done, before returning.
> As Viktor has pointed out, users can always implement blocking themselves
> by writing
>     static <T> CompletableFuture<T> toCompletableFuture(CompletionStage<T>
> stage) {
>         CompletableFuture<T> f = new CompletableFuture<>();
>         stage.handle((T t, Throwable ex) -> {
>                          if (ex != null) f.completeExceptionally(ex);
>                          else f.complete(t);
>                          return null;
>                      });
>         return f;
>     }
>     static <T> T join(CompletionStage<T> stage) {
>         return toCompletableFuture(stage).join();
>     }
> but unlike Viktor, I think it's unreasonable to not provide this for users
> (especially when we can do so more efficiently).  What is happening instead
> is API providers not using CompletionStage as return values in public APIs
> because of the lack of convenient blocking, and instead returning
> CompletableFuture, which is a tragic software engineering failure.
> Re-adding join is easy.  We discourage CompletionStage.toCompletableFuture
> from throwing UnsupportedOperationException, and implement join as:
>     public default T join() { return toCompletableFuture().join(); }
> There is a risk of multiple-inheritance conflict with Future if we add
> e.g. isDone(), but there are no current plans to turn those Future methods
> into default methods, and even if we did in some future release, it would
> be only a source, not binary incompatibility, so far less serious.
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest

More information about the core-libs-dev mailing list