[concurrency-interest] CompletableFuture.whenComplete survey

Peter Levart peter.levart at gmail.com
Mon Dec 21 10:44:39 EST 2015

On 12/21/2015 02:06 PM, Doug Lea wrote:
> On 12/19/2015 11:40 AM, Timo Kinnunen wrote:
>> there’s too much overlap between the whenComplete(BiConsumer) method 
>> and the
>> handle(BiFunction) method.
> Just as a reminder, the initial intent was that handle() translates
> source outcomes, but whenComplete() preserves them.
> This leaves open the policy about what to do if the action in
> whenComplete itself throws an exception, so cannot preserve the
> outcome without losing information. Which is the issue at hand:
> in jdk8, a new exception encountered in whenComplete is dropped
> if the outcome is already exceptional.
> As I've said, regardless of survey results, we should improve
> documentation to more strongly advise users to use handle()
> instead of whenComplete() when intentionally translating outcomes.
> It seems that most users know this already. As far as we know,
> no user has ever complained about jdk8 behavior. The issue was
> noticed while Chris was exploring an alternative implementation of
> CompletionStage, suggesting that we could do better.
> -Doug

It should also be noted that the behavior of the suggested fix to 
improve the situation (the point B in the 2nd survey, which says: "The 
FirstException, with the SecondException as its suppressed exception. In 
other words, preserve but modify the source exception to record the 
SecondException"), while potentially modifying the suppressed exceptions 
list of exceptional outcome of the 1st stage (f1) after it's completion, 
is not that bad because:

- the Throwable.addSuppressed() is a thread-safe operation
- Throwable.getSuppressed() returns a snapshot of exceptions accumulated 

...which means that a potential consumer of the exceptional outcome of 
the 1st stage (f1) will see all the suppressed exceptions that were 
attached to the FirstException before it was thrown in the 1st stage. 
Hypothetical logic processing those suppressed exceptions will not miss 
any of them. It might or might not see the additional SecondException 
attached, and we hope it will not be confused by that.

Spoiler alert: "personal opinion follows". If you intend to vote 
uninfluenced, do so before reading further...

I think that code that handles the exceptional outcome will usually be 
only interested in the type of the main exception, it might also be 
interested in it's cause, but I'm yet to see code that tries to 
reconstruct a meaning from suppressed exception(s). They are usually 
just a diagnostic tool. It would also be sad to loose the property of 
whenComplete() which now guarantees that the exceptional outcome of the 
previous stage is preserved regardless of what whenComplete() action 
does as it might be an action that is not written by the same programmer 
that has written a call to whenComplete().

I've written a thin wrapper for CompletableFuture that presents a 
type-safe API for checked exception handling. It relies on whenComplete 
not changing the type of exceptional outcome. I'm not using this API for 
anything important, but just want to note that any change that makes it 
possible for whenComplete() to change the type of exceptional outcome 
might brake some code that currently relies on assumption that it can't 
be changed.

Regards, Peter

> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest

More information about the Concurrency-interest mailing list