Repository navigation
fix: 释放会话派生缓存与诊断请求底层字符串 - #2923
ranxianglei merged 1 commit into
Conversation
[bot] 🏷 Review 完成。结论先行:可合并(建议人工合并——跨 3 个源模块,不满足 §7.4 自动合并的「单模块」条;其余门禁项全过)。按八问作答: 1. 是什么问题:两条会话派生缓存绕过了会话生命周期与驻留计量——插件工具视图存在模块级 2. 什么原因导致的:存储位置与所有权错位——派生数据挂在「进程级容器」而非「被派生的 Session」上,导致 (a) 释放时机晚于会话淘汰(plugin 视图要等下一次任意 remember 的清扫),(b) 对象图字节计量遍历不到(#2803 的 3. 影响范围与严重程度:长会话/大会话代理进程的驻留内存——OOM 前置因素(#2920 报告了 ~4 GiB heap OOM)。触发条件:插件模式会话(工具视图)+ 任何转发请求(诊断副本)+ 大 body(>512 KiB 时截段钉住全量)。不是功能故障,是内存保留缺陷。 4. 怎么修复的:所有权归位——三类派生数据移入 5. 是否有回归问题:逐项审过既有行为——
6. 是否破坏缓存:不影响前缀缓存/重试/去重键。seam slot 的 digest 语义不变(LCP 归因、be 标记逻辑未动); 7. 是否改了设计方向:没有。是 #2803 已获批准方向的补全(cache ownership 归位),明确不重复其启动索引/warm 集/budget 本体。注意:「统一驻留字节预算能看到这些缓存」这一半收益以 #2803 合入为前提(master 上尚无 8. 是否引入了新的配置:无新 env/config/CLI/默认值。 测试有效性:5 项新测试断言有牙——两项 heap probe 在基线上真实复现(我独立复跑确认失败模式就是内存断言,非导入错误),阈值留 ~4× 余量(16 MiB 上限 vs 实测 4.2 MiB;24 MiB 释放下限 vs 实测 33.5 MiB),forced-GC 测量在重载 CI 上有轻微抖动风险但余量足够;UTF-16 保真测试用尾部孤立 diff 整洁度:干净。8 文件 +186/−35,每行都服务于该机制;architecture.md 新增一条模块说明符合文档纪律;无空行/重排噪音。 查重结论:非重复。open PR 中引用 #2920 的仅此一件;与 #2803/#2776 的关系是声明过的互补(ownership vs budget),范围不重叠。 一处需作者处理的小修(review 发现,分支在外部 fork 我无权直推): |
📦 Merged Build PublishedThis merge to master was published as npm install -g billion-context@0.0.325-master.f8f7d40 # this exact build
npm install -g billion-context@master # always the newest merged build
|
The retention assertions now read the UTF-8 encoding back out of the Buffer slot (byte-equal for valid UTF-8 bodies), and a new test pins that a lone surrogate is retained as U+FFFD — it has no UTF-8 form. Heap-probe thresholds unchanged.
The retention assertions now read the UTF-8 encoding back out of the Buffer slot (byte-equal for valid UTF-8 bodies), and a new test pins that a lone surrogate is retained as U+FFFD — it has no UTF-8 form. Heap-probe thresholds unchanged.
The retention assertions now read the UTF-8 encoding back out of the Buffer slot (byte-equal for valid UTF-8 bodies), and a new test pins that a lone surrogate is retained as U+FFFD — it has no UTF-8 form. Heap-probe thresholds unchanged.
The retention assertions now read the UTF-8 encoding back out of the Buffer slot (byte-equal for valid UTF-8 bodies), and a new test pins that a lone surrogate is retained as U+FFFD — it has no UTF-8 form. Heap-probe thresholds unchanged.
当插件工具视图保存在进程级 Map、缓存诊断请求保存在会话外 WeakMap 时,会话淘汰和驻留字节计量不能完整覆盖它们。此外,512 KiB 的诊断截段可能保留整个大请求的 V8 底层字符串。
这次把工具视图、待结算和已结算诊断请求移入
Session.transient,让它们随会话释放,并让会话对象图的字节计量可以看到这些缓存。诊断截段及有上限的完整副本使用独立 UTF-16 拷贝,保留孤立 surrogate、原来的消息数、摘要、认证指纹和结算行为。持久化仍使用现有显式投影;原文、图片、fork revision 和上游协议格式不变。Fixes #2920.
与已有内存修复的关系
补充 #2803,复用其已获 owner 批准的按需加载和驻留预算,不重复实现启动索引、预算配置或持久化架构。当前 master 上本 PR 已能解除诊断字符串的底层保留,并使会话删除立即释放工具原文;统一的驻留字节预算依赖 #2803。两者在隔离 worktree 中三方合并成功,并验证插件视图与诊断副本都触发预算淘汰、执行中的会话仍固定。
没有新增配置、依赖、kernel 修改、版本变更或持久化迁移。没有修改或重启本机正在运行的 bili。
验证
git diff --check通过;基于当前upstream/master(9972ff2d)。heapUsed + external,不等同进程 RSS/footprint。3823e827的npm test:6499 项,6468 通过、29 跳过、2 失败。失败仅为tests/main-path-transport-retry.test.ts的 主模型请求路径缺少 fail-fast 传输重试:一次 DNS 抖动即打断整轮(acp-loop/preflight 已有 #1263 重试,主路径不对称) #1688 DNS 预算断言、tests/tunnel-guard.test.ts的 403 = 请求被服务端基于权限拒绝 导致任务打断 #1686 unresolvable 断言;两项均在未改 master 基线上复现,本机返回fetch failed / other side closed而非ENOTFOUND/EAI_AGAIN。没有新增失败;没有把全量套件报成全绿。边界
没有做生产会话 heapdump、长期 8GB/OOM 压测或付费真实模型 E2E;上述合成数据证明这两条保留路径得到修复,不能单独证明整个代理的驻留内存问题已经全部解决。已做两轮自查,重点检查调用方、fork、恢复投影及字符串保真。