CompletionStage

Sam Pullara sam at sampullara.com
Sun Jun 30 14:48:43 PDT 2013


On Sun, Jun 30, 2013 at 2:29 PM, Doug Lea <dl at cs.oswego.edu> wrote:

> On 06/30/13 17:00, Sam Pullara wrote:
>
>>
>>     They can (re)throw any exception they like when completed
>> exceptionally.
>>     Which I think gives you the effects you wanted in next few parags of
>>     your mail?
>>
>>
>> This is really ugly. How many wrapping layers might I end up with? I
>> can't just
>> throw the throwable. This is a very common pattern, much more common than
>> rescue() semantics. Very rarely on failure do you want to set the result
>> value.
>>
>>
> This is a good point. When the stage methods were part of
> CompletableFuture, it was too easy and cheap to bother:
> just call completeExceptionally in the function body.
> But maybe there should be some way to get the same effect
> using a stage method.


I'd love to see:

CompletableFuture<T> ifCompletedExceptionally(Consumer<Throwable> block);
CompletableFuture<T> whenCompleted(BiConsumer<T, Throwable> block);

The former is primarily used to do side effects like incrementing counters
and possibly implementing cancellation semantics. The latter is primarily
used like finally for cleanup.


>
>> Why doesn't exceptionally and handle have a CompletionException as the
>> type
>> rather than Throwable if this is the case?
>>
>
> Because of that "generally" disclaimer. You can get out-of-band
> exceptions like OOME that occur while processing the stage itself.
> I do agree that it is annoying. I don't think there's a solution
> to the annoyingness.


It also turns out that completeExceptionally() doesn't wrap the throwable.
I can see this being confusing for users of the API that throwing the
exception and using completeExceptionally() dont result in the same
callback.


>         For cancellation, it doesn't look like there is any way to get the
>> message
>>         downstream. In promises, cancellations go the opposite direction
>> to
>>         exceptions
>>         which means you can react to them. In CompletionFuture it appears
>> that they
>>         don't propagate down to the child CompletableFutures
>>
>>
>>     Yes, they do (unless an intervening handle/exceptionally.)
>>
>>
>> The children will fail with the same exception, but I don't see where
>> they are
>> proactively notified that they are cancelled and should stop work. Hmmm,
>> unless
>>
>
> Do you mean, that we should try to cancel ongoing asyncs?
> For the usual reasons, the best we can guarantee is to not run
> them if they are triggered but haven't started yet. If you want
> to do more, you have to do it yourself, for example, have some
> shared atomic sentinel that they can read. (This is the same
> issue that j.u.c has disappointed you about in the past, and
> Brian has disappointed you about in Streams. It's not that we
> don't like you(!), but no one knows of a reasonable general purpose
> solution to this, and are coming to believe that nothing will ever
> be better than relying on smart developers to roll their own
> special-purpose solutions.)


Yeah, you guys keep claiming that, while I see people with pretty general
solutions getting by just fine — for example, not having
takeWhile/takeUntil on Stream is a real black eye on the API.

Here is the scaladoc for raising a interrupt in Twitter's Future. It works
pretty well for cancellation and other communication from the top where the
bottom may not know anything about what it depends on...

  /**
   * Raise the given throwable as an interrupt. Interrupts are
   * one-shot and latest-interrupt wins. That is, the last interrupt
   * to have been raised is delivered exactly once to the Promise
   * responsible for making progress on the future (multiple such
   * promises may be involved in `flatMap` chains).
   *
   * Raising an interrupt does not alter the externally observable
   * state of the Future. They are used to signal to the ''producer''
   * of the future's value that the result is no longer desired (for
   * whatever reason given in the passed Throwable).
   */

  def raise(interrupt: Throwable)

Sam

-Doug
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/lambda-libs-spec-experts/attachments/20130630/b5b0e674/attachment.html 


More information about the lambda-libs-spec-experts mailing list