New candidate JEP: 462: Structured Concurrency (Second Preview)
Josiah Noel
josiahnoel at gmail.com
Fri Oct 27 20:40:27 UTC 2023
Author intent is one thing I suppose, but for new JDK APIs, I'm usually
focused on how useful a particular feature is to me. Thus, I tried all the
scenarios I could think of to make ShutdownOnSuccess work for me. It
functions as advertised, but I simply can't find any use case for it in my
projects. (perhaps I just lack imagination?) I find myself exclusively
using ShutdownOnFailure or extending STS myself.
On Fri, Oct 27, 2023 at 3:51 PM Eric Kolotyluk <eric at kolotyluk.net> wrote:
> I have tried things out over the evolution of Structured Concurrency, but
> not this specific case.
>
> While I agree that trying things out is a *good *way to see how it works,
> trying things out does not confirm actual architectural or design intent,
> it merely speculates on intent. It would be nice for the architects to
> explicitly specify their intent in JEPs and elsewhere.
>
> But, thanks for the example... did you write it yourself, or have GitHub
> Copilot do it? 😉 Just teasing...
> On 2023-10-27 10:16 a.m., Josiah Noel wrote:
>
> Have you tried it out? Trying this stuff out is the best way to see how it
> works, in any case, observe the following example
>
> try (ShutdownOnSuccess<Integer> scope = new StructuredTaskScope.
> ShutdownOnSuccess<>()) {
>
> var fail =
>
> scope.fork(
>
> () -> {
>
> throw new IllegalAccessException();
>
> });
>
> scope.fork(
>
> () -> {
>
> Thread.sleep(Duration.of(random.nextInt(0, 1000), ChronoUnit.MILLIS));
>
> return 1;
>
> });
>
> scope.fork(
>
> () -> {
>
> Thread.sleep(Duration.of(random.nextInt(0, 1000), ChronoUnit.MILLIS));
>
> return 2;
>
> });
>
> scope.join();
>
> // get first result, (will not care about exceptions as long as one
> succeeds)
>
> scope.result();
>
> // will throw an exception
>
> fail.get();
>
> }
>
>
> Essentially, you must use the `scope.result()` method to retrieve the
> result instead of calling the get methods on a particular subtask
>
> On Fri, Oct 27, 2023 at 12:37 PM Eric Kolotyluk <eric at kolotyluk.net>
> wrote:
>
>> Looks good... thanks.
>>
>> One slight area of confusion for me was,
>>
>> <T> List<Future<T>> executeAll(List<Callable<T>> tasks)
>> throws InterruptedException {
>> try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
>> List<? extends Supplier<Future<T>>> futures = tasks.stream()
>> .map(task -> asFuture(task))
>> .map(scope::fork)
>> .toList();
>> scope.join();
>> return futures.stream().map(Supplier::get).toList();
>> }
>> }
>>
>> static <T> Callable<Future<T>> asFuture(Callable<T> task) {
>> return () -> {
>> try {
>> return CompletableFuture.completedFuture(task.call());
>> } catch (Exception ex) {
>> return CompletableFuture.failedFuture(ex);
>> }
>> };
>> }
>>
>> And what happens if ShutdownOnSuccess is called instead. Eventually I
>> reasoned that the right thing should happen, but there should only ever be
>> one element in the list. Does the scope guarantee only one result?
>>
>> 1. It would be slightly helpful to point this out in a note so that
>> it is more obvious.
>> 2. What is less obvious is that with ShutdownOnSuccess what happens
>> if one or more of the siblings throw an exception?
>> - I would hope that so long at least one task succeeds, this
>> should not cause the overall success of the scope to fail.
>> - It would be nice to see this explained more clearly.
>> - Maybe ShutdownOnSuccess deserves its own example, discussing
>> possible edge cases.
>>
>> Somehow I am remembering Scala 'for comprehensions' with concurrent tasks
>> that 'yield' a result... 😉
>>
>> The current situation seems kinda clunky with using one stream to collect
>> futures, and yet another stream to collect results. Maybe one of the Java
>> architects hates such boilerplate, and will come up with an elegant way to
>> reduce/remove such boilerplate.
>>
>> Sincerely, Eric
>> On 2023-10-27 7:39 a.m., Mark Reinhold wrote:
>>
>> https://openjdk.org/jeps/462
>>
>> Summary: Simplify concurrent programming by introducing an API for
>> structured concurrency. Structured concurrency treats groups of related
>> tasks running in different threads as a single unit of work, thereby
>> streamlining error handling and cancellation, improving reliability,
>> and enhancing observability. This is a preview API.
>>
>> - Mark
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20231027/782677c5/attachment-0001.htm>
More information about the loom-dev
mailing list