[concurrency-interest] CompletableFuture.whenComplete survey, pass 2

Tim Peierls tim at peierls.net
Wed Dec 23 09:50:09 EST 2015


On Wed, Dec 23, 2015 at 7:17 AM, Doug Lea <dl at cs.oswego.edu> wrote:

> Here's another attempt to resolve this issue based on the surveys and
> accompanying discussions.
>
> As the javadocs already note, method whenComplete is intended to
> preserve outcomes. We should further emphasize this by adding:
>
>      * <p> Unlike method {@link #handle}, this method is not designed
>      * to translate completion outcomes, so the supplied action should
>      * not throw an exception.
>

The javadocs weren't at all clear about this intention. The parallels
between the handle and whenComplete javadocs made it very easy for me to
see whenComplete as the void-returning version of handle (although I was
struck by the oddness of the name choices). The first real doubt in my mind
was introduced by Chris Purcell's comment about resource cleanup.

But given the proposed clarification of intent, and (importantly) given the
argument below about avoiding behavioral modification of the CF spec, I now
agree that option B (E1 with suppressed E2) is the best choice.

--tim


An exception thrown in a whenComplete action violates the intent to
> preserve outcomes, so almost any policy (possibly even stating that
> the effects are undefined) might be defensible. However, the one we
> chose (A) allowed an exception to be swallowed, impairing diagnosis of
> usage problems.  Each of the other surveyed options avoids this
> problem, and each them has advantages (and votes).  The only one that
> does not require behavioral modification of the CompletionStage spec
> (rather than just the CompletableFuture implementation) is option B
> (to add the action exception as a suppressed exception of the incoming
> exception).  So this choice does not require change in any other
> implementations of the interface.  Option B also got the most
> "acceptable" votes (in question 2) of survey 2. Here are results
> from the 29 voters. (Questions are repasted below.)
>
> Option  Preferred Acceptable
> A       1         5
> B       4         18
> C       8         12
> D       9         17
> E       4         15
>
> (A few people skipped question 1. Also, some did not include
> question 1 choice in 2. The above table is adjusted to include them.)
>
> Options C and D got more first-choice votes, indicating that they
> probably would have been better choices in the original spec. But the
> pattern of votes suggests that no choice is widely agreed on as enough
> better to risk an interface spec change.
>
> Given all this, I propose we continue with option B (the current
> in-progress jdk9 update) in the CompletableFuture implementation. Plus
> improve the above CompletionStage spec clarification to better describe
> outcomes, as suggested by Joe and others. Here's whenComplete. the
> whnCompleteAsync versions are almost identical.
>
>      * <p> Unlike method {@link #handle}, this method is not designed
>      * to translate completion outcomes, so the supplied action should
>      * not throw an exception. However, if it does, the following
>      * rules apply: If this stage completed normally but the supplied
>      * action throws an exception, then the returned stage completes
>      * exceptionally with the supplied action's exception. Or, if this
>      * stage completed exceptionally and the supplied action throws an
>      * exception, then the returned stage completes exceptionally with
>      * this stage's exception.
>      *
>
> Any objections?
>
> -Doug
>
> ... survey 2
>
> Q1. Given
>
>   CompletableFuture<String> f1 = CompletableFuture.supplyAsync(() -> {
>      if (true)
>         throw new FirstException();
>      else
>         return "A";
>    });
>
>   CompletableFuture<String> f2 = f1.whenComplete((result, exception) -> {
>     if (true)
>        throw new SecondException();
>    });
>
> Where "if (true)" shows the paths of interest in this question. These
> might arise from explicit error checks, programming errors, resource
> failures, and/or translated rethrows.
>
> What should be the completed value of f2?
>
> A. The FirstException. In other words, preserve the source outcome (only)
> if exceptional, ignoring the SecondException.
>
> B. The FirstException, with the SecondException as its suppressed
> exception.  In other words, preserve but modify the source exception to
> record the SecondException.
>
> C. The SecondException. In other words, replace the source outcome
> (whether it is exceptional or not).
>
> D. The SecondException, with the FirstException as its suppressed
> exception.  In other words, replace the source outcome, but if exceptional,
> record it as a suppressedException of the SecondException.
>
> E. A new CompletionException, with the FirstException as its cause and the
> SecondException as its suppressed exception. In other words, indicate that
> throwing an exception in whenComplete is a different form of error.
>
> Q2. Even if you don't prefer them, which of the above choices are
> acceptable?
>
>
>
>
>
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20151223/fe199a79/attachment.html>


More information about the Concurrency-interest mailing list