seata 客户端如何接收响应消息

seata是使用CompletableFuture来处理响应结果的。seata单独封装了MessageFuture类,用来包裹CompletableFuture:

public class MessageFuture {
    private RpcMessage requestMessage;
    private long timeout;
    private long start = System.currentTimeMillis();
    private transient CompletableFuture<Object> origin = new CompletableFuture<>();
}

在AbstractNettyRemoting抽象类中,seata定义了一个futures变量,用来存放MessageFuture信息:

 protected final ConcurrentHashMap<Integer, MessageFuture> futures = new ConcurrentHashMap<>();

在AbstractNettyRemoting抽象类中,发送消息方法sendSyn会将创建MessageFuture实例,并将MessageFuture实例缓存futures中。

 MessageFuture messageFuture = new MessageFuture();
        messageFuture.setRequestMessage(rpcMessage);
        messageFuture.setTimeout(timeoutMillis);
        futures.put(rpcMessage.getId(), messageFuture);

        channelWritableCheck(channel, rpcMessage.getBody());

        String remoteAddr = ChannelUtil.getAddressFromChannel(channel);
        doBeforeRpcHooks(remoteAddr, rpcMessage);

        // 发送消息
        channel.writeAndFlush(rpcMessage).addListener((ChannelFutureListener) future -> {
            if (!future.isSuccess()) {
                MessageFuture messageFuture1 = futures.remove(rpcMessage.getId());
                if (messageFuture1 != null) {
                    messageFuture1.setResultMessage(future.cause());
                }
                destroyChannel(future.channel());
            }
        });

        try {
            // 获取响应结果,如果获取不到会一直等待,直到超时
            Object result = messageFuture.get(timeoutMillis, TimeUnit.MILLISECONDS);
            doAfterRpcHooks(remoteAddr, rpcMessage, result);
            return result;
        } catch (Exception exx) {
            LOGGER.error("wait response error:{},ip:{},request:{}", exx.getMessage(), channel.remoteAddress(), rpcMessage.getBody());
            if (exx instanceof TimeoutException) {
                throw (TimeoutException) exx;
            } else {
                throw new RuntimeException(exx);
            }
        }

客户端在注册Processor时,会通过ClientOnResponseProcessor类,获取futures.

ClientOnResponseProcessor onResponseProcessor = new ClientOnResponseProcessor(mergeMsgMap, super.getFutures(), getTransactionMessageHandler());

这样,客户端在接收到服务端的消息时,会将响应结果set进MessageFuture中:

MessageFuture messageFuture = futures.remove(rpcMessage.getId());
if (messageFuture != null) {
    // 设置响应结果,此时messageFuture.get(timeoutMillis, TimeUnit.MILLISECONDS);获取结果等待结束
    messageFuture.setResultMessage(rpcMessage.getBody());
} else {
    if (rpcMessage.getBody() instanceof AbstractResultMessage) {
        if (transactionMessageHandler != null) {
            transactionMessageHandler.onResponse((AbstractResultMessage) rpcMessage.getBody(), null);
        }
    }
}
posted @ 2023-03-08 11:08  BugsHunter  阅读(59)  评论(0编辑  收藏  举报