Loom EA and using a custom Joiner
mikmoila
mika.a.moilanen at gmail.com
Fri Nov 22 21:49:44 UTC 2024
Yes this is more or less what I already had; I need to return a Stream of TaskResults, including TestFailed - cases:
return switch (subtask.state()) {
case SUCCESS -> {
TaskResult taskResult = subtask.get();
results.add(taskResult); // collect all cases
yield !(taskResult instanceof Completed);
}
case FAILED -> {
firstException.compareAndSet(null, subtask.exception());
yield true;
}
case UNAVAILABLE -> true;
};
> Alan Bateman <Alan.Bateman at oracle.com> kirjoitti 15.11.2024 kello 13.49:
>
>
>
>> 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