Temporal coupling in Fibers and Fibers vs State Machines.

Alex Otenko oleksandr.otenko at gmail.com
Thu Feb 20 10:19:44 UTC 2020


Calling Future.get and CF.join is safe only if you can prove they are
completed. Every other case may deadlock.

Alex

On Thu, 20 Feb 2020, 01:24 Thomas May, <tmay at clearwateranalytics.com> wrote:

> My point was more that the safe actions on a CompletableFuture are
> different depending on the underlying ExecutorService, particular with Loom.
>
> CompletableFuture#join or Future#get is only safe if you do that join from
> a thread in a different pool than the one the Future runs on.
>
> It often becomes a style rule to simply say "Never call
> CompletableFuture#join".  That calculus changes significantly with Loom.
> Join is suddenly perfectly fine  (if not preferred!) over more complex
> then* methods.  It's arguably a lot more readable.
>
> If I have some method which does a lot of future wrangling, how I
> implement it (and even the return type!) will change drastically if
> I think those futures are on an UnboundedExecutorService of virtual
> threads vs a fixed thread pool. (The latter being a bunch of then*
> functions returning a CompletableFuture).
>
> This is where it might help to expose some of that information at the type
> system.  It could be nice if UnboundedExecutorService returned a
> UnboundedFuture or... whatever (I'm terrible at names).
>
> IDK, though, maybe it's enough to just inject an UnboundedExecutorService
> where the futures are made.
> I mean, ultimately, we have things like "ManagedBlocker" which only really
> operates if the pool it runs on is a FJP.  That’s somewhat the same issue.
>
> -----Original Message-----
> From: Ron Pressler <ron.pressler at oracle.com>
> Sent: Wednesday, February 19, 2020 2:20 PM
> To: Thomas May <tmay at clearwateranalytics.com>; loom-dev at openjdk.java.net
> Subject: Re: Temporal coupling in Fibers and Fibers vs State Machines.
>
> > it means you have to start caring at a function level "Is this running
> on a fiber pool or a regular pool”.
>
> I don’t think it does.
>
> Every abstraction, pretty much by definition, hides some implementation
> details.
> Java’s Map and List interfaces hide the cost of their operations; parallel
> streams hide the number of processors, and threads hide the implementation
> of a scheduler.
>
> If you’re writing a real-time application you might care a great deal
> about the implementation of the scheduler — whether it handles priority
> inversion, whether it works in a strict round-robin fashion etc.. Other
> times, you might care less.
> But guess what? Reactive frameworks *also* hide the implementation of the
> scheduler.
> IIRC, the Reactive Streams specification allows the scheduler to schedule
> all operations onto a single thread, and make all operations blocking. So
> you need to care about the implementation of the scheduler to the same
> extent, whether you’re writing synchronous or asynchronous code. Just as
> you pick a scheduler for your asynchronous code, you can pick one for your
> synchronous code.
>
> So I don’t see how threads make caring about scheduling more or less
> important. They just offer a different way of expressing the same
> computation, a way that happens to be more in line with how the Java
> platform — that’s largely organised around the thread abstraction — is
> designed.
>
> - Ron
>
>
> On 19 February 2020 at 20:36:05, Thomas May (tmay at clearwateranalytics.com
> (mailto:tmay at clearwateranalytics.com)) wrote:
>
> > > Martin's concerns are, if by composition he means what I think he
> > > means, if
> > you could set up pieces of computation and functionality and combine
> > them into larger components. If so, these components can have state
> > and those state could change in response to stimuli from other
> > components. Reactive is one of such approach that has individual
> > pieces - operators chained up on a dataflow have internal state
> > tracking when and how their peers can send data and commands to each
> > other. Loom's, and Kotlin's Coroutines instead say you compose via the
> > source code itself, by writing larger and larger methods encompassing
> > a lot of imperative operations. If you have such a method, but for
> > some uses need some retry code, you may be out of luck and have to
> > code yet another set of methods to include that functionality.
> >
> > I believe the concerns are more that things like "CompletableFutures"
> > are hard to intuitively compose correctly.
> >
> > For example, think of a graph of Futures. Now imagine you want to
> > conditionally traverse the graph based on node the values returned by
> each future and cancel the rest based on some condition.
> >
> > With CompletableFutures and traditional threads, that's really
> > difficult without introducing a lot of blocking on some thread. In
> > fact, it's pretty much impossible using the composition methods
> available. You are forced to call `.join()`. This is isn't so bad with loom
> backed completable future but it is a killer for the standard FJP.
> >
> > On the flip side, async/await syntax handles this sort of thing pretty
> > much right out of the box. The awaits all allow the current thread to
> > go do something else useful and, as a bonus, are pretty easy to read.
> The downside is the colored function problem.
> >
> > I believe that is where the composition statement comes into play.
> > Futures and promises are hard to compose correctly. They end up
> > looking ugly and hard to read. Loom helps here, but ultimately, it means
> you have to start caring at a function level "Is this running on a fiber
> pool or a regular pool".
> > If the answer is a regular pool, you run serious risks calling .join()
> if your code is also executing within the same pool.
> >
> > Just my two cents.
> >
> > I still like the loom approach simply because it eliminates the
> > colored function problem without adding extra cognitive burden.
> >
> > ________________________________
> >
> > NOTICE: This e-mail message, together with any attachments, contains
> information of Clearwater Analytics and/or its affiliates that may be
> confidential, proprietary copyrighted and/or legally privileged, and is
> intended solely for the use of the individual or entity named on this
> message. If you are not the intended recipient, and have received this
> message in error, please immediately delete it. The information we provide
> is from sources Clearwater Analytics considers reliable, but Clearwater
> Analytics provides no warranties regarding the accuracy of the information.
> Further, nothing in the email should be construed as legal, financial, or
> tax advice, and any questions regarding the intended recipient's individual
> circumstances should be addressed to that recipient's lawyer and/or
> accountant.
> >
> > Clearwater Analytics, 777 W. Main St, Boise, ID 83702 If you prefer
> > not to receive emails from Clearwater Analytics you may unsubscribe.
>
>
> ________________________________
>
> NOTICE: This e-mail message, together with any attachments, contains
> information of Clearwater Analytics and/or its affiliates that may be
> confidential, proprietary copyrighted and/or legally privileged, and is
> intended solely for the use of the individual or entity named on this
> message. If you are not the intended recipient, and have received this
> message in error, please immediately delete it. The information we provide
> is from sources Clearwater Analytics considers reliable, but Clearwater
> Analytics provides no warranties regarding the accuracy of the information.
> Further, nothing in the email should be construed as legal, financial, or
> tax advice, and any questions regarding the intended recipient’s individual
> circumstances should be addressed to that recipient’s lawyer and/or
> accountant.
>
> Clearwater Analytics, 777 W. Main St, Boise, ID 83702
> If you prefer not to receive emails from Clearwater Analytics you may
> unsubscribe<http://clearwater-analytics.com/unsubscribe>.
>


More information about the loom-dev mailing list