Is there a way to collect Uni.combine().all().unis(...)
failures, as Uni.join().all(...).andCollectFailures()
does?
I need to call different services concurrently (with heterogeneous results) and fail all if one of them fails.
Moreover, what's the difference between Uni.combine().all().unis(...)
and Uni.join(...)
?
Uni Combine Exception The code should be like this,
return Uni.combine().all().unis(getObject1(), getObject2()).collectFailures().asTuple().flatMap(tuples -> {
return Uni.createFrom().item(Response.ok().build());
}).onFailure().recoverWithUni(failures -> {
System.out.println(failures instanceof CompositeException);
CompositeException exception = (CompositeException) failures;
for (Throwable error : exception.getCauses()) {
System.out.println(error.toString());
}
// failures.printStackTrace();
return Uni.createFrom().item(Response.status(500).build());
});
Difference: Quarkus provides parallel processing through use of these two features:
Unijoin - Iterate through a list of objects and perform a certain operation in parallel. Iterate through a list of orders and perform activities on each order one by one (Multi) OR Iterate through a list of orders and add a method wrapper on the object in the Unijoin Builder. When the builder executes, the method wrappers are called in parallel, and its response collected in a list.
List<RequestDTO> reqDataList = request.getRequestData(); // Your input data
UniJoin.Builder<ResponseDTO> builder = Uni.join().builder();
for (RequestDTO requestDTO : reqDataList) {
builder.add(process(requestDTO));
}
return builder.joinAll().andFailFast().flatMap(responseList -> {
List<ResponseDTO> nonNullList = new ArrayList<>();
nonNullList.addAll(responseList.stream().filter(respDTO -> {
return respDTO != null;
}).collect(Collectors.toList()));
return Uni.createFrom().item(nonNullList);
});
You can see the list of objects converted to method wrapper, 'process', which is then called in parallel when 'andFailFast' is called.
'Uni.combine' - Call separate methods that returns different response in parallel.
List<OrderDTO> orders = new ArrayList<>();
return Uni.combine().all().unis(getCountryMasters(),
getCurrencyMasters(updateDto)).asTuple()
.flatMap(tuple -> {
List<CountryDto> countries = tuple.getItem1();
List<CurrencyDto> currencies = tuple.getItem2();
// Get country code and currency code from each order and
// convert it to corresponding technical id.
return convert(orders, countries, currencies);
});
As you see above, both methods in 'combine' returns different results and yet they are performed in parallel.