How to call independent functions parallel and throw exception if one fails using CompletableFuture

Viewed 92

I am try to do something like

Optional<Order> orderDetails = orderRepository.findById(orderId);
if (orderDetails.isEmpty())
    throw new OrderNotFoundException("Order not found!");

Optional<User> UserDetails = userRepository.findById(userId);
if (UserDetails.isEmpty())
    throw new UserNotFoundException("User not found!");

List<OrderItem> ItemDetailsList = orderItemRepository.findByOrderIdOrderByItemIdAsc(orderId);

Where I want to call these three Services methods together in a non-blocking way, but I want to throw error if any one of those call fails and dont proceed furthur. If all of the above works, then execute the later logic.

I am thinking of using allOff() then after that use get on the Futures and do the above logic of throwing error when the Optional is empty?

Is there better way of doing it ? i.e if one of them fails and others are still running, throw error and abort the other running tasks.

1 Answers

CompletableFuture is the wrong tool for the job here. And the main problem is that you want:

"...throw error and abort the other running tasks"

If you read what CompletableFuture::cancel documentation says, you will see that:

mayInterruptIfRunning – this value has no effect in this implementation because interrupts are not used to control processing.

So, even if you call cancel, this will not interrupt your tasks, they will still continue to completition. As such, your fundamental requirement can not be met.

There is a way with creating a custom pool of threads for that CompletableFuture that you want to cancel and shut down the pool, as an example here. But this is not trivial to do and your threads need to respond to interrupts properly.

Related