RFR: jsr166 jdk9 integration wave 2

Peter Levart peter.levart at gmail.com
Tue Nov 24 22:30:26 UTC 2015



On 11/24/2015 06:38 PM, Martin Buchholz wrote:
> Peter: Thanks.  I finally got around to thinking about this.  Your 
> argument against mutating the source Future is a good one.  Even 
> though the extra information will prove useful, you've convinced me 
> that changing the past in this way is going to lead to trouble (like 
> time travel always does in the movies!).
>
> Better behavior seems: always fail with the exception from the failed 
> action, and add the source exception to that as a suppressed 
> exception.  This conveys the same information, but with the exceptions 
> trading places.  Propagating the source exception in preference to the 
> action exception seems wrong because it's the action's job to handle 
> any Throwable, hence propagation should not be the default.  The only 
> downside is that this is slightly less compatible.  Any one who was 
> relying on being able to extract the source exception in this case 
> (unlikely!) will still be able to do that, but will need to change 
> their code to get the suppressed exception.
>

It's a pity that this changes the specification (or at least bends it).

What do you think of exception cloning?

Regards, Peter

>
> On Mon, Nov 23, 2015 at 7:27 AM, Peter Levart <peter.levart at gmail.com 
> <mailto:peter.levart at gmail.com>> wrote:
>
>     Hi,
>
>
>
>     On 11/23/2015 03:12 PM, Doug Lea wrote:
>
>         On 11/23/2015 04:54 AM, Peter Levart wrote:
>
>
>             In CompletableFuture.uniWhenComplete method, the possible
>             exception thrown from
>             BiConsumer action is added as suppressed exception to the
>             exception of the
>             previous stage. This updated exception is then passed as
>             completion result to
>             next stage. When previous stage is appended with more than
>             one asynchronous
>             continuation:
>
>             ...then both secondary exceptions are added as suppressed
>             to the same primary
>             exception:
>
>             This is not nice for two reasons:
>
>             - Throwable::addSuppressed is not thread-safe
>             - The consumer of the result of one CompletableFuture can
>             see the exceptional
>             result being modified as it observes it.
>
>
>         Thanks. The minimal solution is to lock, at least avoiding
>         conflict
>         among multiple whenCompletes:
>
>         !                 else if (x != ex)
>         !                     x.addSuppressed(ex);
>
>         --- 771,781 ----
>
>         !                 else if (x != ex) {
>         !                     synchronized (x) {
>         !                         x.addSuppressed(ex);
>         !                     }
>         !                 }
>
>         This is not as good a solution as your proposal to add
>         Throwable.clone(),
>         but we should do this until something like clone is in place.
>
>
>     Sorry for confusion. I now noticed that Throwable.addSuppressed()
>     and getSuppressed() methods are actually synchronized! I don't
>     know how I missed that...
>
>     So above patch is not needed. Even printing uses getSuppressed()
>     that returns a snapshot. So the only thing remaining is the
>     behavior that exceptions can change while they are being observed.
>     If this is acceptable then this whole report of mine is just a
>     bunch of misinformation.
>
>     Regards, Peter
>
>
>
>             When this stage is complete, the given action is invoked
>             with the result (or
>             null if none) and the exception (or null if none) of this
>             stage as arguments.
>             The returned stage is completed when the action returns.
>             If the supplied action
>             itself encounters an exception, then the returned stage
>             exceptionally completes
>             with this exception unless this stage also completed
>             exceptionally."
>
>             Could specification be tweaked a bit? The last statement
>             leaves it open to what
>             actually happens when "this stage also completes
>             exceptionally".
>
>
>         The looseness was intentional. We'd like to improve
>         debuggability of
>         implementations without strictly promising a particular form
>         in interfaces.
>         This is similar to what's done in ForkJoinTask, where we try to
>         relay exception causes from other threads, but can't promise
>         anything
>         beyond a plain exception.
>
>         -Doug
>
>
>




More information about the core-libs-dev mailing list