英文:
CompletableFuture onTimeout get the supplied value java async programming
问题
我有一个CompletableFuture
链,我在其中传递一个参数(对象),链的每一步都在进行一些工作。我有一些慢的步骤,我想要用超时限制。
我注意到确实会抛出超时异常,但我不知道是哪个参数。
有没有办法在CompletableFuture
API 中获取失败的doWork
方法所传递的参数?
英文:
I have a completablefuture chain to which a pass a parameter (object) and each step of the chain is doing some work.
i have some slow steps which i want to limit with a timeout
what i noticed that indeed the timeout exception is thrown but i have no idea on which parameter
ComplianceCandidate candidate = candidates.poll();
CompletableFuture<ComplianceCandidate> futureTask = CompletableFuture.supplyAsync(() -> candidate, pool)
.thenApply(Task1::doWork).thenApply(Task2::doWork).thenApply(Task3::doWork)
.thenApply(Task4::doWork).thenApply(ProblematicAndSlowTask::doWork).thenApply(AnotherProblematicTask::doWork)
.thenApply(Task6::doWork).thenApply(Task7::doWork).orTimeout(10, TimeUnit.SECONDS)
.exceptionally(ExceptionHandlerService::handle);
completedList.add(futureTask);
is there a way in the completable future api to obtain the parameter passed to the doWork method that has failed?
答案1
得分: 1
这是不可能的,因为正如Holger在评论中解释的那样,orTimeout()
仅适用于您在其上调用的CompletableFuture
。对于导致该future的调用链(或者实际上是图形),没有引用。
但是,您可以通过存储它们的引用来检查所有中间的CompletableFuture
:
CompletableFuture<ComplianceCandidate> init = CompletableFuture.supplyAsync(() -> candidate, pool);
CompletableFuture<Result1> future1 = init.thenApply(Task1::doWork);
CompletableFuture<Result2> future2 = future1.thenApply(Task2::doWork);
…
CompletableFuture<Result7> future7 = future6.thenApply(Task7::doWork);
CompletionStage<Result7> future7OrTimeout = future7.orTimeout(10, TimeUnit.SECONDS);
然后逐个检查它们:
CompletableFuture<ComplianceCandidate> futureTask = future7OrTimeout.exceptionally(throwable -> {
if (!future1.isDone() || future1.isCompletedExceptionally()) {
System.out.println("Task1 failed");
} else if (!future2.isDone() || future2.isCompletedExceptionally()) {
System.out.println("Task2 failed");
} else …
});
(我将根据您实际的调用情况,留给您自行使用循环使代码更加通用。)
英文:
This is not possible because, as Holger explained in the comments, orTimeout()
applies only to the CompletableFuture
you call it on. There is no reference to the call chain (or, in fact, graph) that leads to that future.
You can, however, inspect all intermediate CompletableFuture
s by storing their references:
CompletableFuture<ComplianceCandidate> init = CompletableFuture.supplyAsync(() -> candidate, pool);
CompletableFuture<Result1> future1 = init.thenApply(Task1::doWork);
CompletableFuture<Result2> future2 = future1.thenApply(Task2::doWork);
…
CompletableFuture<Result7> future7 = future6.thenApply(Task7::doWork);
CompletionStage<Result7> future7OrTimeout = future7.orTimeout(10, TimeUnit.SECONDS);
and then check each of them individually:
CompletableFuture<ComplianceCandidate> futureTask = future7OrTimeout.exceptionally(throwable -> {
if (!future1.isDone() || future1.isCompletedExceptionally()) {
System.out.println("Task1 failed");
} else if (!future2.isDone() || future2.isCompletedExceptionally()) {
System.out.println("Task2 failed")
} else …
});
(I let it up to you to make the code more generic with loops depending on what your actual calls are)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论