如何处理Java 8 CompletableFuture中的错误?

时间:2016-09-15 14:16:05

标签: java multithreading concurrency java-8 completable-future

我正在尝试用Java上的WebSockets实现一个简单的类RPC(或请求 - 响应)系统(前端会有JS,但我现在正在后端工作)。

我正在尝试应用Java CompletableFuture模式来异步处理发送消息。但我一直坚持错误处理。

我有一个类(让我们称之为rpc类)负责通过WebSocket会话发送消息(在这里使用Spring WebSocket支持类),然后等待“回复”类型消息,并将它们与待处理请求并将内容返回给调用者。

流程是:

  • 客户端代码调用rpc类上的方法,指定要在远程进程上调用的过程的名称,要向其发送消息的会话以及要发送的参数映射。
  • rpc类使用另一个较低级别的类使用Executor(线程池)异步发送消息,并为“发送消息”操作接收CompletableFuture<Void>
  • 它将待处理的请求存储在地图中,构建CompletableFuture<Map<String, Object>>并将其与待处理的请求相关联,并将它们存储在地图中。它返回了可以完善的未来。
  • 当收到“回复”类型的消息时,会在同一个类上调用一个方法,此方法会尝试将响应与其中一个待处理请求(它们具有此ID)匹配,然后完成{{1与回复中收到的内容。

所以涉及3个线程:调用者线程,发送消息的线程,以及接收消息并完成未来的线程。

现在,我应该如何处理发送消息时的错误(例如IO错误),以使返回的CompletableFuture也失败(或者实现重试策略,以及超时... )?

以下是发送消息的rpc类方法的代码:

completableFuture

1 个答案:

答案 0 :(得分:0)

最简单的方法是使用thencompose()简单地链接期货:

// completeable future for the result. It does nothing, will be completed when reply is received which happen in a different thread, see completeInvocation
CompletableFuture<Map<String, Object>> invocationFuture = new CompletableFuture<>();

CompletableFuture<Void> senderFuture = sender.sendMessage(session, invocationMessage);

// store the pending invocation in the registry
registry.addPendingInvocation(new PendingInvocation(invocationMessage, session, invocationFuture));

// return the future so the caller can have access to the result once it is ready
return senderFuture.thenCompose(__ -> invocationFuture);

如果senderFuture特殊完成,返回的未来也会异常完成,CompletionException将异常作为原因(参见CompletionStage api)。

请注意,您可能还需要解决其他问题:

  • 如果发生异常,您是否还应该取消待处理的调用?
  • 如果响应在调用addPendingInvocation之前到达,会发生什么?在致电sendMessage以避免问题之前,您是否应该打电话给它?
  • 由于您没有对invocationFuture做任何事情,在addPenidngInvocation内创建它不是更好吗?