同时运行Void CompletionStage,但忽略结果

问题描述 投票:1回答:1

我有两个完成阶段方法调用,如果不满足条件,则每个方法调用一个远程服务。它们都是相当长时间运行的进程,我们需要减少延迟。我也不关心secondFuture的响应。它可能返回CompletionStage<Void>,因为我只关心该方法是否在退出main方法之前运行。更加复杂的是,injectedClass2.serviceCall还引发了一个非常重要的异常(404 StatusRuntimeException),需要将其呈现给客户端。

我如何确保第一和第二个future异步运行(彼此不依赖),而第二个future为客户端显示其错误代码和异常。

下面的主要方法是我对此的最佳尝试。它可以工作,但是我希望学习一种更好的实现,该实现可以利用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);
    }

也许超出范围,如何测试/检查两个completionStages是否同时运行?

java asynchronous java-11 completable-future completion-stage
1个回答
0
投票

束缚其他阶段不会改变之前的阶段。换句话说,并行性完全不受您控制,因为它已经被确定。

更具体地说,当您调用injectedClass1.longRunningOp(param1, param2)时,方法longRunningOp的实现决定了如何完成返回的Future。同样,当您调用injectedClass2.serviceCall(param1, param2, someOtherData)时,serviceCall的实现将确定返回的将来的完成情况。两种方法都可以在后台使用相同的执行器,也可以使用完全不同的方法。

唯一可以影响并行性的情况是,这两种方法都在调用者的线程中执行实际操作,以最终返回已经完成的将来。在这种情况下,您必须将每个调用包装到另一个异步操作中,以使其并行运行。但是,在调用者的线程中执行冗长的操作时返回未来是一种奇怪的设计。

© www.soinside.com 2019 - 2024. All rights reserved.