[External] : API proposal for StructuredTaskScope
forax at univ-mlv.fr
forax at univ-mlv.fr
Fri Jan 6 21:02:53 UTC 2023
> From: "Ron Pressler" <ron.pressler at oracle.com>
> To: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "loom-dev" <loom-dev at openjdk.java.net>
> Sent: Friday, January 6, 2023 8:38:09 PM
> Subject: Re: [External] : API proposal for StructuredTaskScope
>> On 5 Jan 2023, at 15:22, [ mailto:forax at univ-mlv.fr |
>> forax at univ-mlv.fr ] wrote:
>> ----- Original Message -----
>>> From: "Ron Pressler" < [ mailto:ron.pressler at oracle.com |
>>> ron.pressler at oracle.com ] >
>>> To: "Remi Forax" < [ mailto:forax at univ-mlv.fr | forax at univ-mlv.fr ] >
>>> Cc: "loom-dev" < [ mailto:loom-dev at openjdk.java.net | loom-dev at openjdk.java.net
>>> ] >
>>> Sent: Thursday, January 5, 2023 3:37:06 PM
>>> Subject: Re: [External] : API proposal for StructuredTaskScope
>>> We have considered such approaches.
>>> One glaring problem is the case of “heterogenous tasks”, i.e. tasks that each
>>> return a result of a different type. This is a very common scenario for
>>> ShutdownOnFailure.
>> I believe that using a static factory instead of a constructor (here
>> StructuredTaskScope.of()) solve that pretty well.
>> If no type is explicitly provided, the inference will default to Object which is
>> exactly what you want in case of a shutdown on failure.
> I don’t follow. The scenario I had in mind is this:
> Response handle() throws ExecutionException, InterruptedException {
> try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
> Future<String> s1 = scope.fork(() -> fetchS1());
> Future<String> s2 = scope.fork(() -> fetchS2());
> Future<Integer> i1 = scope.fork(() -> fetchI1());
> Future< Integer > i2 = scope.fork(() -> fetchI2());
> scope.join() .throwIfFailed();
> return new Response(s1, s2, i1, i2);
> }
> }
> How do you propose to do it when fork returns void?
Ok, I get it, if the result values are heterogeneous, as you said, fork() has to return a Supplier.
try(var scope = StructuredTaskScope.of(Reducer.firstException().shutdownOnFailure())) {
Supplier<Integer> s1 = scope.fork(() -> fetchS1());
Supplier<Integer> s2 = scope.fork(() -> fetchS2());
Supplier<Integer> i1 = scope.fork(() -> fetchI1());
Supplier<Integer> i2 = scope.fork(() -> fetchI2());
Optional<Throwable> result = scope.result();
result.ifPresent(e -> { throw new RuntimeException(e); });
return new Response(s1.get(), s2.get(), i1.get(), i2.get());
}
firstException() returns the first exception as an Optional<Throwable> and shutdownOnFailure() calls shutdown() if there is a failure.
The nice thing is that shutdownOnFailure() is a composable higern order function that can be used not only with firstException() but with any reducers, like toList() by example.
> — Ron
Rémi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20230106/43666d80/attachment.htm>
More information about the loom-dev
mailing list