java - 同时运行 Void CompletionStage 但忽略结果
问题描述
我有两个 completionStages 方法调用,如果不满足条件,每个调用一个远程服务。它们都是运行时间很长的进程,我们需要减少延迟。我也不关心 secondFuture 的回应。它可能会返回CompletionStage<Void>
,因为我只关心该方法是否在我们退出主方法之前运行。一个额外的复杂性是,它injectedClass2.serviceCall
还会引发一个非常重要的异常(404 StatusRuntimeException),需要将其呈现给客户端。
如何确保第一个和第二个未来异步运行(不相互依赖),同时第二个未来为客户端显示其错误代码和异常。
下面的主要方法是我最好的尝试。它可以工作,但我希望学习一个更好的实现,它可以利用 Completables/streams 等。
try {
.
.
.
CompletionStage<Response> firstFuture;
CompletionStage<Response> secondFuture = CompletableFuture.completedFuture(Response.default());
if (condition) {
firstFuture = legacyImplThing.resolve(param1, param2);
} else {
firstFuture =
injectedClass1.longRunningOp(param1, param2);
secondFuture = injectedClass2.serviceCall(param1, param2, someOtherData);
}
final CompletionStage<MainMethodResponse> response =
CompletableFutures.combine(firstFuture, secondFuture, (a, b) -> a)
.thenApply(
v -> ServiceResponse.newBuilder().setParam(v.toString()).build());
handleResponse(response, responseObserver);
} catch (Exception e) {
responseObserver.onError(e);
}
也许超出范围,如何测试/检查两个完成阶段是否同时运行?
编辑:CompletableFutures.combine()
是第三方库方法,不是 java.util.concurrent 包的一部分。
解决方案
链接其他阶段不会改变之前的阶段。换句话说,并行性完全不在您的控制范围内,因为它已经确定了。
更具体地说,当您调用 时injectedClass1.longRunningOp(param1, param2)
,方法的实现longRunningOp
决定了返回的未来将如何完成。同样,当您调用 时injectedClass2.serviceCall(param1, param2, someOtherData)
, 的实现serviceCall
将确定返回的未来的完成。两种方法都可以在幕后使用相同的执行器或完全不同的方法。
您可以影响并行性的唯一情况是,这两种方法都在调用者的线程中执行实际操作,最终返回一个已经完成的未来。在这种情况下,您必须将每个调用包装到另一个异步操作中,以让它们并行运行。但是在调用者的线程中执行冗长的操作时返回一个未来将是一个奇怪的设计。
你的代码
CompletableFutures.combine(firstFuture, secondFuture, (a, b) -> a)
与记录的 API不匹配。一个有效的电话将是
firstFuture.thenCombine(secondFuture, (a, b) -> a)
在这种情况下,您不会影响firstFuture
or的完成secondFuture
。您只是指定两个期货完成后应该发生的事情。
顺便说一句,没有理由指定像(a, b) -> a
in这样的微不足道的函数thenCombine
,而只是链接另一个thenApply
。您可以使用
firstFuture.thenCombine(secondFuture,
(v, b) -> ServiceResponse.newBuilder().setParam(v.toString()).build())
首先。
推荐阅读
- validation - React Form hook - 尽管输入了输入,但仍收到“必填字段”错误消息
- c# - 向下游 HTTPS 终端节点发送消息 AWS IoT Core 规则操作
- ruby-on-rails - 调试时无法访问 ActiveStorage::Attached::One 实例的 url
- javascript - 关于 Set() 和 for..in... in javascript
- sql-server - varchar 类型的 SQL Server 列具有点和破折号 - 右侧转换为十进制
- php - 如何在 woocommerce 注册页面中更改 HTML 表单元素的顺序/位置
- c# - C# Blazor 按钮单击返回 HTTP 错误 400
- python - Scrapy如何在输出中添加“查询网址”作为项目
- socketcan - 向上/向下时的 SocketCAN 行为
- javascript - 未捕获的 ReferenceError:deleted1 未在 HTMLButtonElement.onclick 中定义