Мне нужно загрузить записи из базы данных, а затем последовательно выполнить над ними некоторые действия, и я хочу реорганизовать наш существующий код, чтобы воспользоваться преимуществами API CompletableFuture
основная идея c равно
- a. загрузить записи в очередь b. для каждой записи в очереди выполнить:
- выполнить задачу A (занимает определенное время)
- выполнить задачу B (занимает еще больше времени) на основе задачи A
- выполнить задачу C (также требуется время)
некоторые записи, конечно, заканчиваются раньше, чем другие, поэтому я хочу, чтобы, как только один будет завершен, другой (из очереди) начнет выполнение
У меня есть следующий код
gamesQueue = new PriorityQueue<Game>();
completable = new LinkedList<CompletableFuture<String>>();
Instant start = Instant.now();
Executor pool = Executors.newCachedThreadPool();
DB.getInstance().getConn().useHandle(handle -> {
handle.attach(GameService.class).list().stream().forEach(game -> gamesQueue.add(game));
});
, это загрузит мои записи, тогда я выполняя следующее
while (!gamesQueue.isEmpty()) {
CompletableFuture<String> step1 = CompletableFuture.supplyAsync(this::getCurrentGame, pool)
.thenApply(CapitalLetterTask::capitalize).thenApply(game-> {
if(game.isEndedExceptionaly()) {
handleNumber5Exception(game);
throw new CompletionException(new NumberFiveException(game, "got number 5"));
}
return game;
})
.thenApply(AddStarTask::addStarToGame).exceptionally(ExceptionHandler::handleWeirdEx);
completable.add(step1);
}
while (!completable.isEmpty()) {
CompletableFuture<String> completed = completable.poll();
if (completed.isDone()) {
try {
log.debug("result: {}", completed.get());
} catch (Exception ex) {
}
} else if(completed.isCompletedExceptionally()) {
try{ //never enters here
log.debug("This is a bad result:{} ", completed.get());
}catch(Exception ex) {
}
}
else {
completable.add(completed);
}
}
Instant end = Instant.now();
Duration duration = Duration.between(start, end);
log.debug("Total time: {}", duration.getSeconds());
loadGames(); <-- call itself
}
, я не доволен своей обработкой исключений, более того, я вижу, что даже фьючерсы, которые должны были быть пойманы на первом этапе, все еще передаются дальше по цепочке
what я хотел бы спросить, как реализовать его таким образом, чтобы каждый метод мог генерировать свое собственное исключение, пойманное и обработанное, не передавая его дальше по цепочке