Repository navigation
Conversation
内容已经 sync 流程合入(dev 收编记录:未检索到),本提交为作者署名落账(提交页归属)。 Co-authored-by: Ver-zhzh <225828202+Ver-zhzh@users.noreply.github.com>
|
感谢这份修复——注释里把「为什么被观察会话是泄漏源」(listener 摘不干净 → 长期 pin 住整个环)和「为什么淘汰是安全的」(每次 append 都已 flush 到磁盘,重放走 审了一遍现状,有一个收编对账和两个请求: 收编对账:三项改动里的前两项已随
所以本 PR 目前真正待收编的只剩 请求 1(rebase 收窄): 请求 2(补回归测试):两个文件里没有任何测试——淘汰条件收敛是会话生命周期逻辑,值得一个回归测试钉住行为,建议覆盖至少三个场景:① 无 agent/running + 有 listener + 静默超 另外说明一下账目:#445 已以 completed 关闭,但其标题里「会话常驻淘汰被跳过」这一半的修复就在本 PR 的差集里——在本 PR 合并前,这个缺口不要丢。如果后续以单独 issue 立账或直接收编本 PR 差集都可以,保持追踪即可。这两项补完后我这边可以立刻核验。再次感谢! |
- evictLoadedBeyondCap:被 SSE 观察但静置超 idleAgentTtlMs 的会话允许淘汰 (此前一律跳过,长生命周期 SSE 标签页把完整内存环永久钉住); 淘汰前 flushDeltaBuf/flushToolResultBuf,重连走 getEvents→ensureEvents 从磁盘重放,不丢事件;idleAgentTtlMs<=0 保持旧的被观察永不淘汰。 - evictLoadedBeyondCap(exceptId?):ensureEvents 刚载入的会话不受同一次 淘汰扫描影响,避免刚读回的日志被同一调用立即丢弃。 - 新增回归测试 session-evict-watched-idle.test.ts(3 场景)。 注:本 PR 原含 maxEventBytes 64MB→8MB、effectiveAfterRestart 两项, 已由上游 abb7628(v3.30.0 republish)自行收编;rebase 到最新 main 后 diff 已收窄到只剩本项(按评审要求)。 Closes huiliyi37#445
7b99cad to
4dffbed
Compare
|
两项已补完,请核验: 请求 1(rebase 收窄):已 rebase 到最新 main(含 abb7628)。diff 已收窄到只剩第三项—— 请求 2(回归测试):新增 另:实现测试时发现并顺手修了一个边界—— #445 的「会话常驻淘汰被跳过」缺口仍在本 PR 差集里,未丢。 |
evictLoadedBeyondCap 淘汰 watched-idle 会话后 eventsLoaded=false, 但 adoptExternalSessions 的漂移合并与 mergeExternalEvents 的 await 后守卫都只看 eventsLoaded,导致活着的 SSE listener 永远 收不到外部新事件(session-rehydrate LRU 压力测试回归)。 放宽两处资格判定为 eventsLoaded || listeners.size > 0: 无 listener 的已淘汰会话仍不参与合并(内存继续释放); 只合并 seq > session.seq 的尾部新事件,不全量常驻; getEvents→ensureEvents 磁盘重放路径未动。
|
rework 后 CI 新红已定位并修复(commit 107a56d,已 push,CI 重跑中)。 回归:rework 让 watched-idle 超 TTL 会话被淘汰(eventsLoaded=false、listeners 保留),但 修复(仅 验证:tsc 0 报错;session-rehydrate 73/73、session-evict-watched-idle 3/3、session-manager 133/133;另跑 session-tail-memory/replay-batch/events-trim/replay-compaction/manager-goal/runtime-pool 44/44 全过。 设计说明:淘汰 watched 会话只丢事件日志、保留订阅;有外部进度到达时走漂移合并做尾部重读+扇出,SSE 语义恢复为“不断连即可实时收到”,同时 #445 的常驻内存泄漏目标不受影响。 |
|
rework 后 CI(run 38182650980,commit 107a56d)已跑完,汇报结论:
无需返工,等待核验。 |
|
已完成审查,并按本项目的收编流程移植合入开发主仓 main,提交 本次采纳了 watched-idle 超 TTL 淘汰、当前打开会话保护,以及淘汰后 SSE 外部进度推送。审查后另补强了两处边界:无持久化读取能力时保留被观察历史;已淘汰会话接收外部进度时不重新积累脱离 LRU 管理的事件环。还增加了其他会话都受保护时,同步/异步打开历史的压力用例。 验证:会话相关 517 项测试、类型检查通过;6 类隔离缺陷还原均触发行为断言。行数预算仍有既有失败,本次未新增违规;Windows 桌面长期堆增长仍需实机复测。 当前完成的是开发主仓收编,尚未同步公开仓,因此此 PR 暂保持打开;公开仓同步和收编关闭流程完成后再更新状态。 |
|
已通过 sync 流程合入 dev,感谢 @Ver-zhzh 的贡献 🎉 本 PR 的改动(fix(server): sidecar 会话事件日志内存上限收敛(#445))已经 sync 流程合入主仓(本次 sync),并已收录进 CONTRIBUTORS.md。 按仓库的双仓流程,公开仓 PR 不经 merge 按钮合入(保持 dev 主仓唯一事实源),现以 sync-merged 标记关闭。欢迎继续贡献! |
修复:sidecar watched-idle 会话事件日志可淘汰(#445 差集)
1. evictLoadedBeyondCap 的 listeners 跳过条件收敛
现象:淘汰函数遇到
s.agent || s.running || s.listeners.size > 0的会话就跳过——SSE listener 摘不干净时会话永不淘汰,只进不出;长生命周期 SSE 标签页把完整内存环永久钉住(内存泄漏)。根因:
src/server/session-manager.ts的evictLoadedBeyondCap跳过条件把「被 SSE 观察但长期静置」的会话也视为不可淘汰。修复:收敛为——
!s.agent && !s.running且事件已静置超过idleAgentTtlMs的被观察会话允许淘汰(先flushDeltaBuf/flushToolResultBuf再清 events/eventsLoaded,语义与既有unloadSession同);重连走getEvents→ensureEvents从盘回放,不丢事件;idleAgentTtlMs <= 0保留旧行为(永不淘汰被观察会话)。另加exceptId参数:ensureEvents刚载入的会话不受同一次淘汰扫描影响,避免刚读回的日志被同一调用立即丢弃。未修观察(如实报告,非本批引入)
loadRecords只读轻量记录、loadedOrder为空),无需改动。replay-compaction.ts及 agent 层,根因不在本批改动范围,未深挖。验证
session-evict-watched-idle.test.ts(评审要求的 3 场景:超 TTL 被观察会话被淘汰且可磁盘重放 / 未超 TTL 不淘汰 /idleAgentTtlMs<=0永不淘汰)npm testsession-manager 相关套件CI 说明(非本批引入的红)
本 PR 基线(rebase 到 v3.30.0 republish 后)在同一基线上的 main CI 同样失败:
windows-smokefailure、ci (24)failure(上游基线预存问题,本地已核验)。本批改动只涉及 server 侧session-manager.ts的淘汰逻辑 + 1 个新测试文件,与 windows-smoke 跑的 bash/path-expression 测试无交集;tsc + session 单测本地全绿。故两处红为上游 CI 环境/基线问题,非本批引入。Closes #445