Temporal coupling in Fibers and Fibers vs State Machines.
Thomas May
tmay at clearwateranalytics.com
Thu Feb 20 01:24:22 UTC 2020
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