[External] : Re: A new build and a new structured concurrency API

Remi Forax forax at univ-mlv.fr
Tue Nov 16 15:10:38 UTC 2021



On November 16, 2021 2:26:13 PM UTC, Alan Bateman <Alan.Bateman at oracle.com> wrote:
>On 16/11/2021 13:51, forax at univ-mlv.fr wrote:
>> :
>> I've decided to focus on the high-level API first.
>> I agree that separating the low-level API and allow anyone to create more high level APIs is a good design.
>> For me the low-level API which is almost synonymous of StructuredExecutor.
>>
>> Do we agree that ShutdownOnSuccess/ShutdownOnFailure are examples of the kind of high level APIs that can be written ?
>>
>> I believe that passing the StructuredExecutor at construction helps to solve several issues.
>> As i said, it ties a little more the lifecycle of the Handler policies to the lifecycle of the StructuredExecutor.
>> It also allows to avoid to have a method accept() to be part of the public API (see below).
>> There is also no problem to use several policies with each one taking the same StructuredExecutor.
>> It's less flexible than the current API because you can share a policy handler between several different StructuredExecutors but i see that more as something bug prone than as a feature.
>>
>> Currently, the API is creates from two parts,
>>    StructuredExecutor.fork(Callable, BiConsumer)
>> and
>>    BiConsumer.accept(StructuredExecutor, Future)
>>
>> For me, this handshake should be secret and not part of the public API given that
>> - StructuredExecutor.fork(Callable, BiConsumer) should not be part of the public API because users should either use the variant without a BiConsumer or use the BiConsumer/Handler API which can be better tailored to the use case the policy handler want to solve
>> - BiConsumer.accept(StructuredExecutor, Future) should not be part of the public API because users don't care at all about how this is implemented.
>>
>> By example with a SPI, that make StructuredExecutor.fork(Callable, BiConsumer) non visible in StructuredExecutor
>>    public class StructuredExecutorSPI {
>>      public static <V> Future<V> fork(StructuredExecutor executor, Callable<? extends V> callable, Consumer<? super Future<V>> completerConsumer) {
>>        return ...
>>      }
>>    }
>>
>>
>> ShutdownOnSuccess can be written like this:
>>
>>    public class ShutdownOnSuccess<V, X extends Exception> {
>>      private final StructuredExecutor executor;
>>
>>      public ShutdownOnSuccess(StructuredExecutor executor) {
>>        this.executor = executor;
>>      }
>>
>>      public Future<V> fork(CallableWithException<V, X> task) {
>>        return StructuredExecutorSPI.fork(executor, task::call, future -> {
>>          // do something with the executor and the future
>>        });
>>      }
>>
>>    ...
>> }
>You've addressed a potential misuse but your sketch means that 4 classes 
>define a fork method. We've been trying to keep it simple with the fork 
>methods in one place. Where you need something other than ShutdownOnXXX 
>then it's easy to implement a BiConsumer without needing to introduce 
>another interface/class for implementations.
>
>I've no doubt that the API will go through several iterations. I think 
>we need to some usage before doing another iteration.

as I said, the SPI is too much.

But do you agree that the method accept in ShutdownOn* should be hidden / not part of the public API ?

>
>-Alan.

Remi

>
>
>
>
>
>
>

-- 
Envoyé de mon appareil Android avec Courriel K-9 Mail. Veuillez excuser ma brièveté.


More information about the loom-dev mailing list