Search code examples
quarkusmutiny

How to deal with whole compensation using Mutiny?


Working on Quarkus and SmallRye Mutiny, I don't know how to deal with compensations.

I have a list of employees and I have to update all of them in the database. The Data Access Object (EmployeeDao) has the following method: public Uni<Boolean> update(Long id, String name, Long deptId). It expect to receive the Employee's fields.

Also, I have to return a Uni<Boolean> to notify if all the updates went fine or not. Something as is given below:

public Uni<Boolean> updateEmployees(List<Employee> employees) {
    for(Employee employee: employees) {
        //TODO: Execute or compensate
    }
}

My question is, how can I iterate one by one performing the update process and dealing with compensation?

In case of failure in any employee update process, I'd like to try several times and, after that, if I couldn't update an employee, I have to undo all the employees before returning any response. The idea is to keep the database in a consistent state.

How to deal with whole compensation using Mutiny?


Solution

  • If I understand correctly, you want to execute a set of async operations and combine them. For this, you can do something like:

    List<Uni<?>> list = new ArrayList();
    for(Employee employee: employees) {
       Uni<Void> uni = update(employee);
       list.add(uni);
    }
    
    return Uni.combine().all().unis(list)
       .with(list -> { /* all employees have been updated */ return true; })
       .onFailure().call(failure -> {
           Uni<?> uni = compensate();
           return uni.onItem().transform(x -> false);
       });
    
    

    The first look collects Unis for each update. Then we combine these. If everything is fine, we are good and return true. If something bad happens, we compensate and return false.