Repository navigation
fix(session): keep RPC routing alive across reconnects - #810
Conversation
Reviewer's GuideThe PR hardens reverse-tunnel RPC routing across reconnects by retaining and selecting the newest per-peer session, preserving mappings during overlapping disconnects, surfacing synchronous send failures, and retrying briefly while connectivity stabilizes; integration tests cover the reconnect and timeout scenarios. Sequence diagram for RPC retry during peer reconnectsequenceDiagram
participant Caller
participant SessionManager
participant SessionWorker
participant ProtoEndpoint
participant ProtoServer
participant Peer
Caller->>SessionManager: sendRpcRequest
SessionManager->>SessionWorker: sendAsyncRequest
SessionWorker->>ProtoEndpoint: asyncRequestWithHandler
ProtoEndpoint->>ProtoServer: asyncRequest
ProtoServer->>ProtoServer: onSend
alt session unavailable or send fails
ProtoServer-->>ProtoEndpoint: false
ProtoEndpoint-->>SessionWorker: false
SessionWorker-->>SessionManager: false
SessionManager->>SessionManager: scheduleRpcRetry
SessionManager->>SessionWorker: sendAsyncRequest
else newest session accepts request
ProtoServer->>Peer: SendAsync
ProtoServer-->>ProtoEndpoint: true
ProtoEndpoint-->>SessionWorker: true
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="src/lib/common/session/protoendpoint.h" line_range="31-32" />
<code_context>
- // async call request and with 3s timeout result callback
- void asyncRequestWithHandler(const std::string &target, const proto::OriginMessage &request, RpcHandler resultHandler);
+ // async call request and with 3s timeout result callback. Returns false
+ // when the request could not be handed to the session at all.
+ bool asyncRequestWithHandler(const std::string &target, const proto::OriginMessage &request, RpcHandler resultHandler);
// Send a one-way frame to a specific peer. It does not create a request
</code_context>
<issue_to_address>
**Send failures are reported as accepted**
When an Android RPC cannot be handed to the session, `SessionWorker::doAsyncRequest` ignores the `asyncRequestWithHandler` result and returns `true`, so callers treat the unsent RPC as accepted and drop it without retry or failure handling.
Return the result of `asyncRequestWithHandler` from Android’s `SessionWorker::doAsyncRequest`.
</issue_to_address>851527f to
ae550e0
Compare
a827357 to
2c5e661
Compare
ae550e0 to
38646d6
Compare
3947d06 to
c5ee806
Compare
38646d6 to
2753fb4
Compare
c5ee806 to
2178710
Compare
2753fb4 to
eb2e0fb
Compare
The server kept one session per peer address. When a reconnect registered a new session before the old one was torn down, the new entry was dropped and the old session's disconnect then erased the address entirely, so B -> A requests silently stopped being delivered. Keep every session, route to the newest, and skip routing cleanup while another session for the same peer remains. Also surface synchronous send failures and briefly retry RPCs that no endpoint could accept. Log: keep RPC routing alive across reconnects PMS: TASK-396845 Influence: B -> A requests keep being delivered when a peer reconnects.
eb2e0fb to
54fc556
Compare
deepin pr auto review🤖 AI 代码审查报告📊 总体评价
🔍 详细分析1. 语法逻辑 ✅评价: 语法正确,逻辑清晰 ✅ 通过 潜在问题: 建议: ['建议在asyncRequest的early future检查处补充更详细注释,说明FBE框架在onSend返回0时会让future立即就绪并携带异常,因此需要通过get()检测并返回false'] 2. 代码质量 ✅评价: 代码结构清晰,注释完整 ✅ 通过 潜在问题: 建议: ['将waitFor辅助函数提取到tests/common/test_utils.h等共享头文件中', '将protoserver.cpp中的std::cout替换为DLOG/WLOG日志宏,与其他文件保持一致'] 3. 代码性能 ✅评价: 性能良好,资源使用合理 ✅ 通过 潜在问题: 建议: ['若未来需要根据不同网络环境调优重试参数,可考虑从配置文件或环境变量读取'] 4. 代码安全 🔒评价: 存在0个安全漏洞 ✅ 通过
安全漏洞详情: 建议: [] 💡 改进建议代码示例// 建议:将protoserver.cpp中的std::cout调试输出替换为日志框架
// 修改前:
// std::cout << "hasConnected: " << ip << " true" << std::endl;
// 修改后:
// DLOG << "hasConnected: " << ip << " true";
// 建议:将测试中的waitFor辅助函数提取到共享头文件
// tests/common/test_utils.h
// #pragma once
// #include <QElapsedTimer>
// #include <QTest>
// #include <functional>
// inline bool waitFor(const std::function<bool()> &condition, int timeoutMs = 3000)
// {
// QElapsedTimer timer;
// timer.start();
// while (!condition() && timer.elapsed() < timeoutMs)
// QTest::qWait(10);
// return condition();
// }本报告由 AI 代码审查工具自动生成 |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: lzwind, re2zero The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Part 7/8 of the reverse tunnel stack (recovery of #803).
This reapplies the reviewed commit on top of the corrected stack because #803 was accidentally merged into its stacked base branch instead of master.
Merge order: #805 → #806 → #807 → #808 → #809 → #810 → #811.
Retargeted to master after #809 merged.
The server kept one session per peer address. When a reconnect registered
a new session before the old one was torn down, the new entry was dropped
and the old session's disconnect then erased the address entirely, so
B -> A requests silently stopped being delivered.
Keep every session, route to the newest, and skip routing cleanup while
another session for the same peer remains. Also surface synchronous send
failures and briefly retry RPCs that no endpoint could accept.
Log: keep RPC routing alive across reconnects
PMS: TASK-396845
Influence: B -> A requests keep being delivered when a peer reconnects.
Summary by Sourcery
Keep peer-to-peer RPC delivery alive across reconnects by routing through replacement sessions and retrying temporarily unavailable endpoints.
Bug Fixes:
Enhancements:
Tests: