Skip to content

fix(hermes): 保证最后一轮 capture 先于 session flush#479

Open
Qiyuanqiii wants to merge 1 commit into
TencentCloud:mainfrom
Qiyuanqiii:fix/issue-235-hermes-session-flush-race
Open

fix(hermes): 保证最后一轮 capture 先于 session flush#479
Qiyuanqiii wants to merge 1 commit into
TencentCloud:mainfrom
Qiyuanqiii:fix/issue-235-hermes-session-flush-race

Conversation

@Qiyuanqiii

Copy link
Copy Markdown

关联 Issue

Related to #235

背景与定位

本 PR 是一个独立的 Hermes 生命周期正确性修复,不新增 Gateway client、MCP bridge 或平台适配器。

它不修改 #470#476,也不与 #316/#372 的共享客户端和 MCP 基线竞争。

问题根因

Hermes 的 sync_turn() 会为每轮 capture 创建后台线程,以避免阻塞模型响应;但正常的 on_session_end() 不会等待这些线程,而是立即调用 Gateway /session/end

因此最后一轮 capture 较慢时,实际顺序可能变成:

POST /session/end -> Gateway flush -> POST /capture

Gateway 会先完成旧状态的 flush,最后一轮 capture 随后才写入并通知 scheduler。宿主此时已经认为会话结束,新增工作可能停留在未 flush 状态。

本地使用阻塞假客户端稳定复现出了:

end -> capture

此外,原实现先把 Thread 注册到 _active_syncs,释放锁后才调用 start()。session end 如果恰好插入这个窗口,会把“已登记但尚未 alive”的合法 capture 当作无效线程清除。

修复方案

  • capture Thread 在 _sync_lock 内完成登记和启动,关闭注册窗口
  • on_session_end() 读取并等待当前已登记的 capture
  • 使用 5 秒总等待预算,避免会话结束钩子无限阻塞
  • capture 在预算内完成时,立即按 capture -> end 顺序 flush
  • 超过预算时,让 on_session_end() 有界返回
  • 后台延迟 flush 线程继续等待 capture,完成后再调用 /session/end
  • 没有在途 capture 时保持原有立即 flush 行为
  • 完成后清理 _active_syncs 中的失效线程引用

范围边界

本 PR 仅修改 Hermes provider 和对应标准库测试,不涉及:

  • Gateway HTTP 协议
  • capture 幂等实现
  • 共享 Gateway client
  • MCP、Claude Code、Dify 或 AI SDK 适配器
  • scheduler、store 或记忆提取逻辑
  • 新增 Python 依赖

验证

python -m unittest discover -s hermes-plugin/memory/memory_tencentdb/tests -p test_session_end_ordering.py -v
python -m py_compile hermes-plugin/memory/memory_tencentdb/__init__.py hermes-plugin/memory/memory_tencentdb/tests/test_session_end_ordering.py
npm test
npm run build
git diff --check origin/main...HEAD

验证结果:

  • Hermes 定向测试:4/4 通过
  • 项目完整测试:4 个文件、67 项通过
  • Python 编译检查:通过
  • 插件及三个脚本构建:通过
  • diff 检查:通过

验证截图

image

@Qiyuanqiii

Qiyuanqiii commented Jul 12, 2026

Copy link
Copy Markdown
Author

仍值得继续挖的下一优先级是 Gateway JSON 请求边界:当前畸形 JSON 会落入 500,请求体也没有大小上限,可拆成一个返回 400/413、支持中止并有定向测试的小型协议修复。user_id 真正租户隔离和跨重启持久化幂等也有价值,但改动范围明显更大,我想询问维护者这个方向是否有价值去做,还有就是#470能否审阅一下

@Maxwell-Code07

Copy link
Copy Markdown
Collaborator

hank you for submitting this PR and participating in Tencent Rhino-bird Open-source Training Program!
We have successfully received your submission. The program is currently in full swing, and we will complete the Code Review for you as soon as possible. Please keep an eye on the status notifications for this PR so you can follow up promptly once the review feedback is provided.
Thanks again for your contribution and open-source spirit! 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants