[concurrency-interest] map over j.u.c.CompletableFuture with strict threading semantics

Viktor Klang viktor.klang at gmail.com
Sat Oct 21 12:06:20 EDT 2017


Hi Sebastian,

On Sat, Oct 21, 2017 at 2:01 PM, Millies, Sebastian <
Sebastian.Millies at softwareag.com> wrote:

> Hi,
>
>
>
> I’m sorry to be so dense, but can you explain what the difference is to
> simply upstream.thenApplyAsync(f, YOUR_INTENDED_EXECUTOR) ?
>

Sorry, on my way to the airport, and I might have misunderstood your
question, but think about "Which thread adds the transformations" vs "Which
thread executes the transformations". (There needs to be a happens-before
relationship between "all transformations already added" and "intended
executor executes the value which produces the first result"—so that all
the transformations are piggybacked on that executor and not the thread
which adds the transformation.)

Cheers,
√


>
>
> n  SebaSTIAN
>
>
>
> *From:* Concurrency-interest [mailto:concurrency-interest-
> bounces at cs.oswego.edu] *On Behalf Of *Viktor Klang
> *Sent:* Friday, October 20, 2017 8:06 PM
> *To:* Dimitar Georgiev
> *Cc:* concurrency-interest
> *Subject:* Re: [concurrency-interest] map over j.u.c.CompletableFuture
> with strict threading semantics
>
>
>
> Dimitar,
>
>
>
> Just a note: I realized that you can probably get to what you want by
> controlling injecting a "valve"—CompletableFuture, and only complete that
> once you want the transformations to be applied:
>
>
>
> Pseudocode (since I'm having lunch):
>
> enum Trigger { On; }
>
> CompletableFuture<X> upstream = …
>
> CompletableFuture<Trigger> upstreamTrigger = new
> CompletableFuture<Trigger>()
>
>
>
> CompletableFuture<Y> result = upstream.thenCombineAsync(upstreamTrigger,
> (x, discard) -> x, YOUR_INTENDED_EXECUTOR).thenApply(…).thenCompose(…)…
>
>
>
> upstreamTrigger.complete(Trigger.On); // this will trigger the execution
> of the transformations on YOUR_INTENDED_EXECUTOR regardless of what
> transformations are added to `result` as long as they HAPPEN-BEFORE the
> execution of this line.
>
>
>
> YMMV,
>
>
>
>>
>
>
>
>
>
>
> On Fri, Oct 20, 2017 at 5:32 PM, Dimitar Georgiev <
> dimitar.georgiev.bg at gmail.com> wrote:
>
> Thanks Viktor! I had not thought of it this way, and you are absolutely
> right.
>
> I hope it is okay to expand the discussion a little bit and go a bit
> off-topic from j.u.c. Viktor probably already sees where this is
> going. Next is flatMap:
>
> public static <A, B> CompletableFuture<B> flatMap(CompletableFuture<A>
> future, Function<A, CompletableFuture<B>> f);
>
> Semantics my app requires here: if the result of f() is completed on a
> new threading context, I want subsequent map / flatMap operations to
> use that context. If not (if the result of f() is pure, i.e. of the
> form new CompletableFuture<>().complete(value)), continue in the same
> threading context.
>
>  Viktor, your remark leads me to think there is no sane way to achieve
> this semantics with an eager future implementation such as
> CompletableFuture. I would need something lazy which is a description,
> creating the thing be referentially transparent, and
> submission/execution be decoupled from creating the thing.
>
> To finish the off-topic with the actual question:
> - Does such a thing exist in the Java ecosystem at all? I know it does
> in Scala, but I need a Java alternative.
>
> P.S. I found a couple of months ago https://github.com/traneio/future.
> A claim is made that the threading semantics are what I just
> described, but it is an eager future. I will look into the
> implementation in the coming days; I expect it to be something along
> the "workaround" Viktor described. Myself, I don't feel I am smart
> enough or have the testing and formal verification tools to go down
> that path...
>
>
>
>
>
>
>
> On 20 October 2017 at 17:52, Viktor Klang <viktor.klang at gmail.com> wrote:
> > Hi Dimitar,
> >
> > In general this is not possible, nor desirable, since completion is
> likely
> > to happen *before* a transformation is added.
> >
> > However, there is nothing technical which prevents you to create an
> > implementation of CompletionStage which stores a reference to the
> Executor
> > to be used, and runs transformations which are applied to it on that
> > Executor unless some other Executor is specified.
> >
> > --
> > Cheers,
> > √
> >
> >
> > On Oct 20, 2017 09:41, "Dimitar Georgiev" <dimitar.georgiev.bg at gmail.com
> >
> > wrote:
> >
> > Sorry if this has already been discussed.
> >
> > I need to implement the following function:
> >
> > public static <A, B> CompletableFuture<B> map(CompletableFuture<A>
> > upstream, Function<A, B> f);
> >
> > It's pretty apparent what the function does. However, it has the
> > requirement that f() be always executed in the thread where upstream
> > is completed. (That is, if upstream is completed non-exceptionally,
> > since if it was not, f will not be called so there is no threading
> > semantics concerning f)
> >
> > Is this possible with j.u.c.CompletableFuture?
> >
> > Regards, Dimitar
> > _______________________________________________
> > Concurrency-interest mailing list
> > Concurrency-interest at cs.oswego.edu
> > http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> >
> >
>
>
>
>
>
> --
>
> Cheers,
>
>>
> Software AG – Sitz/Registered office: Uhlandstraße 12, 64297 Darmstadt,
> Germany – Registergericht/Commercial register: Darmstadt HRB 1562 -
> Vorstand/Management Board: Karl-Heinz Streibich (Vorsitzender/Chairman),
> Eric Duffaut, Dr. Wolfram Jost, Arnd Zinnhardt, Dr. Stefan Sigg; -
> Aufsichtsratsvorsitzender/Chairman of the Supervisory Board: Dr. Andreas
> Bereczky - *http://www.softwareag.com* <http://www.softwareag.com>
>



-- 
Cheers,
√
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20171021/d7783aeb/attachment.html>


More information about the Concurrency-interest mailing list