Example in support of CompletionHandler

Alan Bateman Alan.Bateman at oracle.com
Tue Nov 15 08:45:14 UTC 2022


On 14/11/2022 17:33, Anthony Vanelverdinghe wrote:
> :
>
> While upgrading my Loom experiments to the current API, I noticed 
> `CompletionHandler` has disappeared.
>
> One of the experiments was to process a file by splitting it into 
> blocks and processing each block in parallel.
> To do so, I created a generic method which would do (1) the 
> block-splitting, (2) map each block to a result, and (3) collect the 
> results.
> For (2) and (3) I'd pass in a functional interface as argument.
>
> The method I had was something like:
>
> ```java
> <T> void process(Path file, Function<ByteBuffer, T> mapper, 
> CompletionHandler<? super T> collector) {
>     try (var executor = StructuredExecutor.open()) {
>         for(each block) {
>             executor.fork(() -> mapper.apply(block), collector);
>         }
>         executor.join();
>     }
> }
> ```

This is StructuredExecutor, so I guess these examples were built using 
one of the early prototypes.

The issue with the CompletionHandler approach is that the policy 
implementation, and the API for consuming the outcome, ended up being a 
mix of task scope and completion handler implementation. The outcome 
from many iterations on this was that was clearer to implement the 
policy and API in one place.

In your example, I think you would get better abstraction if the caller 
of "process" is unaware that the method uses a StructuredTaskScope. It 
might be that process works on the file sequentially in some cases, 
maybe concurrency in other cases. This should be transparent to the 
caller. If "collector" is just collecting results then another 
functional, maybe something as simple as Consumer<? super T>, might be 
enough here.

FWIW, there is an example in the javadoc that implements a "collector" 
to collect the results of tasks that complete successfully.

-Alan


More information about the loom-dev mailing list