Loom EA and using a custom Joiner

Alan Bateman alan.bateman at oracle.com
Fri Nov 15 11:49:33 UTC 2024



On 15/11/2024 07:47, Mika Moilanen wrote:
> Hello,
>
> I've been playing around with the latest EA 
> (https://openjdk.org/jeps/8340343) build with Joiners et al.
> I'm building a small utility which reads a list of http requests from 
> a file and runs them concurrently. These tasks have an associated test 
> which is an assertion about the http response.
> Tasks can either succeed or they can fail in two ways:
>
> 1) expected failure: test or its execution can fail
> 2) something unexpected outside of the test execution e.g NPE happens.
>
> Task are self-contained and TaskResponse contains all the data needed 
> for reporting the outcome to the user:
>
> sealed interface TaskResult {
>   record Success(....) ...
>   record TestFailed(... ) .. // test failed
>   record Failure(...) ... // something else failed e.g an exception 
> during the http call
> }
>
> In case of successfull SubTask I need to check if the TaskResult is 
> TestFailed or Failure, and shutdown the scope preventing processing of 
> tasks, and report about the outcome.
> In case of any SubTask if failing I need only the exception from the 
> last SubTask::exception().
>
> I started with a StructuredTaskScope.Joiner.allUntil(<a predicate 
> which examines TaskResult>) but noticed that join() doesn't throw, and 
> thus proceeded in implementing a custom Joiner which stores the last 
> exception and overrides result and onComplete - methods.
>

I think this is more about adaptation which can be done when forking or 
when the subtask completes, both will work.

At fork time it could be:

   Callable<T> adapt(Callable<TaskResult<T>> task) { .. }

and the default joiner or Joiner.awaitAllSuccessfulOrThrow will work as 
the onComplete will be called with a successful or failed subtask.

If you want join to return a TaskResult, or stream of, then it will 
require a custom Joiner that extracts the exception when a subtask 
succeeds with TaskFailed, the onComplete will look something like:

         @Override
         public boolean onComplete(Subtask<? extends TaskResult<T>> 
subtask) {
             if (subtask.state() == Subtask.State.SUCCESS) {
                 return (subtask.get() instanceof 
TaskResult.TestFailed<T> failed)
                         && FIRST_EXCEPTION.compareAndSet(this, null, 
failed.exception());
             } else {
                 return true;  // cancel unconditionally
             }
         }

which may be what you have already.

-Alan


More information about the loom-dev mailing list