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