Temporal coupling in Fibers and Fibers vs State Machines.
Alex Otenko
oleksandr.otenko at gmail.com
Thu Feb 20 12:41:03 UTC 2020
Not just self-reference.
When talking about Future.get, one should not say "it blocks just one
Thread [we can afford it]". Instead, say "it blocks one Thread at a time".
It becomes obvious that such use can block an arbitrary number of threads,
so thread pools with upper bound on size will eventually deadlock.
Alex
On Thu, 20 Feb 2020, 12:34 Ron Pressler, <ron.pressler at oracle.com> wrote:
> > My point was more that the safe actions on a CompletableFuture are
> different depending on the underlying ExecutorService
>
> Almost anything you do in a concurrent context depends on the scheduler.
> Whether
> blocking on *anything* will ever complete, or equivalently, whether a task
> submitted for execution will ever run, depends on the fairness of the
> scheduler.
>
> In fact, on operating systems that do time-slice-based preemption, any
> piece
> of code can stop running at any time and never continue. So when we write
> a;b
> and assume that b will run if a terminates, we rely on an implicit
> assumption
> that the scheduler is fair.
>
> > 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.
>
> I am not familiar with this rule. I believe that CompletableFuture.join,
> when running on FJP, will help execute tasks. I believe you are referring
> to the possibility of a self-deadlock, but this, too, has implicit
> assumptions. Depending on the implementation of the future, as well as of
> the
> scheduler, any blocking operation could potentially never terminate.
>
> - Ron
>
>
> On 20 February 2020 at 01:24:30, Thomas May (tmay at clearwateranalytics.com
> (mailto: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
> > Sent: Wednesday, February 19, 2020 2:20 PM
> > To: Thomas May ; 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.
>
>
More information about the loom-dev
mailing list