I have two processes which should start in parallel and if the first process fails, I should use second process result. I came up with the following code. Is there any sensible way to simplify it?
final CompletableFuture<Data> mainFut = mainProcess(...);
final CompletableFuture<Data> backupFut = backupProcess(...);
final CompletableFuture<Data> resultFut = new CompletableFuture<>();
mainFut.handle((r, t) -> {
if (t == null) {
resultFut.complete(r); // main process is fine, use its result
} else {
LOGGER.error("Main process failed, using backup", t);
backupFut.handle((rb, tb) -> {
if (tb == null) {
resultFut.complete(rb); //backup is fine, use its result
} else {
resultFut.completeExceptionally(tb); //backup failed too
}
return null;
});
}
return null;
});
return resultFut;