[External] : Re: Future.resultNow / exceptionNow
Remi Forax
forax at univ-mlv.fr
Mon Nov 22 21:36:18 UTC 2021
----- Original Message -----
> From: "Brian Goetz" <brian.goetz at oracle.com>
> To: "Alex Otenko" <oleksandr.otenko at gmail.com>
> Cc: "loom-dev" <loom-dev at openjdk.java.net>
> Sent: Lundi 22 Novembre 2021 22:12:38
> Subject: Re: [External] : Re: Future.resultNow / exceptionNow
>> The implementation of a completion policy is spread across two places:
>>
>> - the handler(s) passed to SE::fork
>> - the code following the call to SE::join
>
> I'll add that it is harder to see this because the two policies we've
> specified -- have ad-hoc result states and APIs -- and also have methods
> that fuse state access with side effects. (In other words, they're
> typical bespoke OO APIs.) One could imagine a more functional approach,
> where all handlers had a more regularized API:
>
> interface Handler<S> {
> void accept(StructuredExecutor se, Future<?> task);
>
> S state();
> }
>
> where S would be an algebraic data type (sum of products) representing
> the state. Then we might define ShutdownOnFailure as implementing
> Handler<SOFStates> where:
>
> sealed interface SOFStates {
> record AllGood() extends SOFStates { }
> record GotException(Exception e) extends SOFStates { }
> }
>
> then using it would look like:
>
> try (var executor = SE.open()) {
> var handler = new ShutdownOnFailure();
>
> // forking and joining
>
> switch (handler.state()) {
> case AllGood _ -> return Stream.of(future1, future2)...;
> case GotException(var e) -> throw new WAE(e);
> }
> }
>
> I'm not suggesting that we do, or don't, redefine the handler API like
> this; I'm offering this as an explanation of why it might have been hard
> to see the relationship between the policy states and the code that
> follows the join. By regularizing the policy states, we ask handler
> writers/users to engage in some more ceremony (declaring an ADT for
> their state), but regularizing their API and giving users a stronger
> nudge towards proper usage.
You can standardize the API without having the method state() at the interface level.
In your example, you call ShutdownOnFailure::state() not Handler::state().
And why stop at having a method state() on the Handler and not make fork() and join() part of the Handler API too.
It will be a useful simplification because you will be able to merge join() + state() into one method most of the time.
And you can have a specialized version fork() by example to return a Future or not depending on the semantics of the Handler.
Rémi
More information about the loom-dev
mailing list