Skip to content

Commit d726c31

Browse files
committed
feat: 将 RPC 请求处理改为异步 CompletableFuture 模式
1 parent 6b5202f commit d726c31

4 files changed

Lines changed: 42 additions & 48 deletions

File tree

rpc-core/src/main/java/com/xiaoyu/rpc/core/client/ByteBuddyProxyFactory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
5050
}
5151

5252
RpcRequest request = builder.build();
53+
// 注意:这里直接返回 Future。
54+
// 此时要求业务接口 Method 的返回类型必须是 CompletableFuture,否则会发生类型转换异常。
5355
return rpcClient.sendRequest(request, method.getReturnType());
5456
}
5557
})).make().load(clazz.getClassLoader()).getLoaded().getConstructor().newInstance();

rpc-core/src/main/java/com/xiaoyu/rpc/core/client/RpcClient.java

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,40 +25,39 @@ public RpcClient() {
2525
this.transportClient = transport.createClient();
2626
}
2727

28-
public Object sendRequest(RpcRequest request, Class<?> returnType) {
28+
public java.util.concurrent.CompletableFuture<Object> sendRequest(RpcRequest request, Class<?> returnType) {
2929
try {
30-
// 1. 服务发现
30+
// 1. 服务发现 (同步查找,通常有本地缓存)
3131
InetSocketAddress address = serviceDiscovery.lookupService(request.getInterfaceName());
3232

3333
if (address == null) {
34-
throw new RuntimeException("未发现服务: " + request.getInterfaceName());
34+
java.util.concurrent.CompletableFuture<Object> future = new java.util.concurrent.CompletableFuture<>();
35+
future.completeExceptionally(new RuntimeException("未发现服务: " + request.getInterfaceName()));
36+
return future;
3537
}
3638

37-
// 2. 使用传输层发送请求
38-
// 注意: TransportClient 返回的是反序列化后的结果(RpcResponse)或者已经提取的数据
39-
// 在 NettyTransportClient 实现中,我们返回了 RpcResponse 对象
40-
Object result = transportClient.sendRequest(request, address);
39+
// 2. 使用传输层发送请求 (返回的是异步 Future)
40+
java.util.concurrent.CompletableFuture<Object> transportFuture = transportClient.sendRequest(request,
41+
address);
4142

42-
// 3. 处理结果 (这一步逻辑如果 NettyTransportClient 已经做了反序列化,这里可能有点冗余,但保持检查是好的)
43-
if (result instanceof com.xiaoyu.rpc.common.vo.RpcResponse) {
44-
com.xiaoyu.rpc.common.vo.RpcResponse response = (com.xiaoyu.rpc.common.vo.RpcResponse) result;
43+
// 3. 异步处理结果 (链式调用 thenApply)
44+
return transportFuture.thenApply(result -> {
45+
if (result instanceof com.xiaoyu.rpc.common.vo.RpcResponse) {
46+
com.xiaoyu.rpc.common.vo.RpcResponse response = (com.xiaoyu.rpc.common.vo.RpcResponse) result;
4547

46-
// 数据已经在 TransportClient 中反序列化了吗?
47-
// 查看 NettyTransportClient 代码:
48-
// return rpcResponse; -> 它并没有反序列化 data 字段成 returnType
49-
// 所以这里需要反序列化
48+
byte[] data = response.getData().toByteArray();
5049

51-
byte[] data = response.getData().toByteArray();
52-
53-
com.xiaoyu.rpc.common.serialization.Serializer serializer = com.xiaoyu.rpc.common.serialization.SerializerCode
54-
.getSerializerByCode(RpcConfig.getInstance().getSerializerCode());
55-
return serializer.deserialize(data, returnType);
56-
}
57-
58-
throw new RuntimeException("Unexpected response type: " + result.getClass());
50+
com.xiaoyu.rpc.common.serialization.Serializer serializer = com.xiaoyu.rpc.common.serialization.SerializerCode
51+
.getSerializerByCode(RpcConfig.getInstance().getSerializerCode());
52+
return serializer.deserialize(data, returnType);
53+
}
54+
throw new RuntimeException("Unexpected response type: " + result.getClass());
55+
});
5956

6057
} catch (Exception e) {
61-
throw new RuntimeException("RPC请求发送失败", e);
58+
java.util.concurrent.CompletableFuture<Object> future = new java.util.concurrent.CompletableFuture<>();
59+
future.completeExceptionally(e);
60+
return future;
6261
}
6362
}
6463
}

rpc-core/src/main/java/com/xiaoyu/rpc/core/transport/TransportClient.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public interface TransportClient {
1414
*
1515
* @param request 请求对象
1616
* @param address 目标地址
17-
* @return 响应结果 (CompletableFuture 或 直接结果)
17+
* @return 响应结果 (CompletableFuture)
1818
*/
19-
Object sendRequest(RpcRequest request, InetSocketAddress address);
19+
CompletableFuture<Object> sendRequest(RpcRequest request, InetSocketAddress address);
2020
}

rpc-transport-netty/src/main/java/com/xiaoyu/rpc/core/transport/netty/NettyTransportClient.java

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ protected void initChannel(SocketChannel ch) {
5353
}
5454

5555
@Override
56-
public Object sendRequest(RpcRequest request, InetSocketAddress address) {
56+
public CompletableFuture<Object> sendRequest(RpcRequest request, InetSocketAddress address) {
5757
String protocolName = RpcConfig.getInstance().getProtocol();
5858

5959
try {
@@ -73,13 +73,6 @@ public Object sendRequest(RpcRequest request, InetSocketAddress address) {
7373

7474
// Generate ID and set to request
7575
String requestId = java.util.UUID.randomUUID().toString();
76-
// Use reflection or builder if setter not available, but since we regenerated
77-
// proto, we should use builder properly
78-
// However, RpcRequest is immutable if generated by Proto?
79-
// Wait, RpcRequest.java is generated. It has a Builder.
80-
// But the signature of sendRequest takes RpcRequest, which is already built.
81-
// We need to rebuild it with the ID.
82-
8376
RpcRequest.Builder builder = request.toBuilder();
8477
builder.setRequestId(requestId);
8578
RpcRequest newRequest = builder.build();
@@ -88,25 +81,25 @@ public Object sendRequest(RpcRequest request, InetSocketAddress address) {
8881
clientHandler.addFuture(requestId, resultFuture);
8982

9083
Protocol protocol = ProtocolFactory.getProtocol(protocolName);
91-
// Pass the handler so protocol can ensure it's in pipeline if needed (double
92-
// check)
9384
protocol.sendRequest(channel, newRequest, clientHandler);
9485

95-
Object result = resultFuture.get(5, TimeUnit.SECONDS);
96-
97-
if (result instanceof RpcResponse) {
98-
RpcResponse rpcResponse = (RpcResponse) result;
99-
100-
if (!"Success".equals(rpcResponse.getMessage())) {
101-
throw new RuntimeException("服务端报错: " + rpcResponse.getMessage());
86+
// 彻底移除 resultFuture.get(),直接返回异步 Future
87+
return resultFuture.thenApply(result -> {
88+
if (result instanceof RpcResponse) {
89+
RpcResponse rpcResponse = (RpcResponse) result;
90+
if (!"Success".equals(rpcResponse.getMessage())) {
91+
throw new RuntimeException("服务端报错: " + rpcResponse.getMessage());
92+
}
93+
return rpcResponse;
94+
} else {
95+
throw new RuntimeException("服务端返回的不是 RpcResponse 类型");
10296
}
103-
return rpcResponse;
104-
105-
} else {
106-
throw new RuntimeException("服务端返回的不是 RpcResponse 类型");
107-
}
97+
});
10898
} catch (Exception e) {
109-
throw new RuntimeException("RPC请求发送失败", e);
99+
log.error("RPC请求发起失败", e);
100+
CompletableFuture<Object> future = new CompletableFuture<>();
101+
future.completeExceptionally(e);
102+
return future;
110103
}
111104
}
112105
}

0 commit comments

Comments
 (0)