Skip to content

[PR] fix: bound ordinary session loads and narrow lazy field reads - #4750

Merged
ranxianglei merged 12 commits into
ranxianglei:masterfrom
z0d0dOr:2026-10-25_bounded-session-load
Oct 30, 2026
Merged

ranxianglei merged 12 commits into
ranxianglei:masterfrom
z0d0dOr:2026-10-25_bounded-session-load

Conversation

@z0d0dOr

@z0d0dOr z0d0dOr commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

Large ordinary cold loads hydrated every historical message and retained all raw block rows alongside the decoded view. Restoring dropped metadata or block contents also rebuilt an entire Session, twice when a save touched both lazy fields.

This change reads blocks in batches of 32 and fetches only the unique tail/plugin-snapshot message seqs. A shared incremental decoder preserves inactive blocks, archived/orphan originals, pointer order, repeated-message identity and tail-gap reporting. SQLite deferred read snapshots and dedicated async SQLite/MySQL connections keep all pages, CAS content and media hydration on one generation.

Lazy field getters now read just their requested indexed fields plus the existing envelope arbitration. A synchronous save shares that projection when both fields are dropped. Existing freshness/drift rules, missing-store failures and one/full normalization remain intact. The rollback-guard test helper now closes SQLite before deleting its temporary directory on Windows.

Validation:

  • 14 targeted test files: 59 passed, 4 skipped, 0 failed. Skips: two better-sqlite3 cases (optional driver unavailable), MySQL contract and MySQL e2e (no DSN). Dedicated MySQL connection/CAS/media behavior is covered by a fake-driver test; a real MySQL run remains for configured CI.
  • TypeScript check, production build, unused-export check and git diff --check passed.
  • Read-only comparison on one 8,591-message / 242-block database snapshot: all-row loader observed heap peak 239.6 MiB; bounded loader sampled peak 153.3 MiB (~36% lower). Complete restored view and original-content hashes matched. Retained heap remained about 125 MiB; this measures one load, not whole-server memory or elimination of every OOM path. No private conversation contents are included.

The envelope still needs full parsing for source arbitration, and final original contents remain resident. This batch changes no schema, configuration or runtime installation and does not include request-lifetime, admission-control or streaming-write changes.

Fixes #4739

@ranxianglei ranxianglei changed the title fix: bound ordinary session loads and narrow lazy field reads [PR] fix: bound ordinary session loads and narrow lazy field reads Oct 25, 2026
@ranxianglei

Copy link
Copy Markdown
Owner

🤖 Powered by ework · qwen3.8-27b

(ai: vllm-qwen/qwen3.8-27b)

查重: 不重复。检索了 open/closed issue 与全部在途 PR(100 条)——没有第二个 PR 触碰「普通加载全量物化消息行 / lazy 字段窄读」这条路径。相关但不重叠:#4532/#4540(验证侧的流式 digest/分批验证,不同机制)、#4522(ingestSession 只取 block 覆盖行,写路径)、#4619(quick_check 移出关键路径,启动路径)。本 PR 是 #4739 的修复 PR,一单一 PR。

标签: bug + scope/storage + p1(存储层、跨车道;大活跃历史下内存耗尽属 p1 口径)。

开始按 PR review 规范审:①方向核对 #4739 → ②回归清点(改动前既有行为逐项过)→ ③代码审查 → ④测试有效性 → ⑤diff 整洁度。PR head 24f781e(单 commit,12 文件 +1110/−197),base master bb7c2497。先拉分支读 diff,结论稍后按八问体例回复。

@ranxianglei ranxianglei added bug Something isn't working p1 scope/storage labels Oct 25, 2026
@ranxianglei

Copy link
Copy Markdown
Owner

🤖 Powered by ework · qwen3.8-27b

(ai: vllm-qwen/qwen3.8-27b)

Review 结论:方向正确(修根因,非遮症状)、代码质量过硬标准、回归审计逐项通过;5 个红片共 14 个失败测试全部为 master 级继承性簇失败(A/B 字节级同签名实证),已按 CI 协调政策把 origin/ci-fixes(tip 1fa9373)合入分支并推送(24f781e81..ba50d87da),本地定向全绿。建议 CI 重跑转绿后合并。

结构化八问

  1. 是什么问题:大会话加载的内存放大——冷加载把全部历史消息行都水合(最终视图只需要 tail/pluginSnapshot 指针);dropped metadata/blockContents 恢复时各重建一次整个 Session,一次 save 触碰两个 lazy 字段就重建两次。实测 5,043 消息会话 heap 15→230 MiB、retained ~118 MiB。
  2. 什么原因导致的:getMessages/getBlocks 没有收窄与分页手段,viewFor/viewForAsync 只能「全取再解码」;lazy 字段 getter 复用 loadSync(整会话加载)作数据源,字段级读取被抬到会话级成本。本 PR 收敛的是读取面本身(narrow seq 集 + 32 行分页 + 单代快照 + 窄字段读),不是出口侧过滤。
  3. 影响范围与严重程度:p1 级内存放大,数据正确性不受影响(一直是对的,只是用量超)。触发条件 = 大会话普通冷加载 / save 触碰双 lazy 字段;用户面 = 大会话场景 OOM/进程死亡风险。修复后作者 A/B 实测峰值降 ~36%(239.6→153.3 MiB);retained heap 仍 ~125 MiB(final originals 需驻留,已如实披露,属后续独立工作)。
  4. 怎么修复的:① 窄读——messages 只取 tail/pluginSnapshot seq 去重并集(IN 子句,保持 ORDER BY seq 与 gap 语义),blocks 按 32 页读、逐页释放原始 CAS 串;② 单代快照——SQLite 同步路径用 deferred 事务(不占写锁),异步/MySQL 用独立连接 + REPEATABLE READ 一致性快照,CAS 内容与 media 水合同一代完成;③ lazy 字段改窄读——只读请求的 indexed 字段,原有 envelope 仲裁逻辑原样保留,同步 save 在双 drop 时共享一份投影(reentrancy-safe);④ LegacyViewBuilder 增量装配,ref 账本/state 字段/orphan journal/tailGaps 语义不变。
  5. 是否有回归问题:对触碰路径的既有行为逐项审计(对照 base bb7c249 逐条验证):
    • 源仲裁:新 loadResidentFields 的 drifted/non-drifted 选择与 loadSync 逻辑等价(active 计数 = COUNT active=1,与 base shadow.activeBlockCount 同源;mapped refs = COUNT DISTINCT 非 BLOCKED,与 byRef 规模一致;requests/nextBlockId 比较式相同含数字串 coercion)——通过;
    • SQL 兼容:getMessages/getBlocks 不传 opts 时查询与 base 逐字节相同,现有调用点(export/verify/import/rawMessages/tailViewRows)全部不传 opts——通过;
    • 视图内容:与旧全行装配字节相等(assert.deepEqual 钉住),含 ghost/BLOCKED ref 原文保留、orphan journal 优先、空 vs 缺指针语义、tailGaps 计数、重复消息身份——通过;
    • 页面/快照失败 → 整体 load 返回 null,部分视图不外泄,下次 load 正常恢复(有测试钉住)——通过;
    • 有意行为变更(披露):lazy 字段恢复不再触发 loadSync 附带的 import/save 调度/ref restamp 副作用(旧路径 miss 时可能写索引)。这是读取面清理,索引会在下次 save 自然收敛,无用户可见差异;
    • wire 格式、配置面、持久化格式、kernel:未触碰——不涉及。
  6. 是否破坏缓存:不涉及。未动前缀缓存/prefix affinity/去重键;消息身份仍按 seq/content hash 原口径。
  7. 是否改了设计方向:不涉及。既有存储读取路径内的实现优化,接口变更为向后兼容的可选参数(不传即旧语义)。
  8. 是否引入新配置:不涉及。无 env/config/schema/version 变更。

测试有效性(④):三个新测试文件有牙——字节级 parity 断言、spy 钉死(lazy 读取不触发任何整载/import/save/viewFor)、MySQL fake driver 断言精确快照 SQL 串 + 连接路由 + rollback/release 计数、仲裁真值表(6 行覆盖 drift-latch tie-break)并与公开 loadSync 选代交叉核对、页面失败恢复、空 vs 缺语义。storage-backend-contract 新增的真 MySQL readSnapshot 段已在 CI mysql-contract lane(mysql:8.0 service,job 绿)实际执行验证。

CI 处置(继承性实证):5 个红片的 14 个失败测试名(storage-render golden ×4、engine-proofs ×6、plugin-fork ×1、orphan-freeze ×1、opencode-inline ×1、blogfeed default probing ×1)与 #4599 在册簇逐一吻合。实证:4 个簇测试文件在干净 master(bb7c249)与 PR head 上跑出完全相同的失败(同一断言文本、同一 digest 漂移,66/77 同 11 败)——本 PR 零新增失败。merge ci-fixes 后本地定向:簇文件 77/77 过、PR 自测 28 pass/2 skip(better-sqlite3 驱动缺失)、web-blogfeed 8/8、launcher-opencode-inline 2/2。opencode-inline 为 Windows 在册 flaky 簇(仅单片出现),ci-fixes 尚无对应修复;若重跑再红属继承,已在 #4599 留言归口。

diff 整洁度(⑤/⑤b):12 文件每行均与目标相关;命名达意(LegacyViewBuilder/readResidentFieldsFor/buildRecordForSave);restoreBlockContents 抽公共消除两处重复;注释带 # 出处讲为什么;风格与仓库一致;无死代码/魔法数字。未发现需要补修 commit 的问题。

判定:代码与行为层面可合;等 CI 重跑绿(opencode-inline 若再红见 #4599)后请 owner 合并。

@ranxianglei

Copy link
Copy Markdown
Owner

🤖 Powered by ework · qwen3.8-27b

[bot] 🏷 进度更新(进程曾被看门狗重启,现汇报状态):

Review 已完成(八问结论见上一条回复):方向正确、代码干净、回归审计通过;原 5 个红片 14 个失败全部为继承性簇(#4599 在册,A/B 字节级同签名实证),已把 origin/ci-fixes(1fa9373)合入分支推送(ba50d87),本地定向全绿。

新动态:ba50d87da 之上作者又推了两个 test-only commit(均针对我标记的 Windows 残留红):

  • 66297ff97 test: honor Windows cmd wrapper for inline OpenCode launch —— launcher-opencode-inline.test.ts 的断言原先平台盲写(command === fakeOc),Windows 上 [bug] Windows: a space in the client or -e path truncates the launch (spawn shell:true, unquoted) — and silently kills compression when only the command is quoted #679 的 cmd.exe 包装必然使其失败。已核对源码 planClientSpawn(src/launcher.ts:5398-5425):win32 下 .cmd/.bat/无扩展名命令确实走 comspec /d /s /c "<line>" + windowsVerbatimArguments:true,新断言与真实行为逐参数吻合(含 quoteWinToken 的空格引号规则),不是「让测试过」的糊弄修法;顺带移除了 HOME/USERPROFILE 覆盖(XDG_CONFIG_HOME 隔离足够)。
  • 610b164e1 test: close fork session stores before Windows cleanup —— plugin-fork harness 的 store.cancelAll() → store.closeQuietly(),与本 PR 自己 persist-rollback-guard 的 Windows 修复同类(SQLite 句柄未关导致临时目录删除失败)。

两个 commit 本地实测 51/51 通过(Linux 路径)。

当前 CI:新 head 610b164e1 已触发,23 个 gate 排队中,test 矩阵随后展开;旧 head 的运行被新 push 取消属正常。等 CI 出结果即可,无需 owner 操作;若全绿建议直接合并。若 opencode-inline/plugin-fork 在 Windows 仍红,我会按 #4599 归口继续跟进。

@ranxianglei

Copy link
Copy Markdown
Owner

🤖 Powered by ework · qwen3.8-27b

[bot] 🏷 Review 收工总结(此前已发八问结论与进度更新,此为最终状态确认):

已完成:

  1. 查重:不重复;标签 bug/p1/pr/scope/storage 已打;
  2. 全 diff(12 文件/1692 行)对照 base bb7c249 逐项审计——源仲裁逻辑、SQL 兼容性、视图语义、默认值全部等价,无缺陷;唯一有意行为变更(lazy 字段恢复不再触发 import/save 调度副作用)已在八问中披露;
  3. CI 5 个红片 14 个失败全部实证为继承性簇(CI Control Center: Centralized CI Failure Handling & Status Sync (Comment all CI issues here; do not open new issues) | CI 总控: CI 失败集中处理与状态同步(所有 CI 问题在此评论, 勿开新 issue) #4599 在册):干净 master 与 PR head 失败签名字节级一致,本 PR 零新增失败;已按政策 merge origin/ci-fixes(1fa9373)进分支推送(ba50d87),本地定向全绿(簇 77/77、PR 自测 28 pass/2 skip);
  4. 作者后续两个 test-only commit(66297ff Windows cmd wrapper 断言、610b164e1 plugin-fork closeQuietly)已核对源码行为并本地实测 51/51。

当前状态:CI 正在新 head 610b164e1 上排队运行(23 gate + test 矩阵随后)。代码与行为层面 review 通过,等 CI 转绿即可合并;若仍有红我会按 #4599 归口跟进并留言。无需 owner 操作。

Preserve background integrity checks and their cache while retaining consistent sync/async read snapshots. Keep both MySQL snapshot and fork-clone contract tests, and combine Windows COMSPEC detection with exact launcher argument checks.

Validation: 61 targeted tests passed, 3 optional backend cases skipped; TypeScript, build, and diff checks passed.
Windows SIGTERM terminates the child instead of running its graceful
shutdown handler. Trigger the existing loopback shutdown route on Windows
so the draining-marker regression exercises the same lifecycle as POSIX.

Wait for child close before deleting its database, destroy sockets owned
by the silent TCP fixture, and stop health polling when the child exits.
Keep both regression scenarios and their behavioral assertions intact.

Validation: the isolated CI-preloaded serial test file passes 6/6 and exits
naturally in 11.58 seconds; npm run typecheck and npm run build pass.
Windows CI can reset an aborted probe connection instead of ending it.
The silent TCP fixture did not handle errors on accepted sockets, so
ECONNRESET became an uncaught test exception after the probe finished.

Destroy reset sockets and add a real resetAndDestroy regression against
the same fixture. Keep the existing port-owner and ladder assertions.

Validation: the new regression reproduces ECONNRESET before the fix;
the isolated CI-preloaded serial test file then passes 7/7 and exits
naturally. Pure tsc and git diff --check pass.
@ranxianglei

Copy link
Copy Markdown
Owner

🤖 Powered by ework · qwen3.8-27b

[bot] (ai: vllm-qwen/qwen3.8-27b)

冲突已解决并推送。 把 master 合入 PR 分支(merge commit,不 rebase,保留外部贡献者历史),PR 恢复可合并,新 head 46ad1110f 的 CI 全绿(30 项检查:0 失败、0 待跑,其余为按门控跳过的 e2e 车道)。

结构化八问:

  1. 是什么问题: PR [PR] fix: bound ordinary session loads and narrow lazy field reads #4750(限制普通会话加载 + 收窄懒字段读取)与 master 冲突(dirty)。分支上次同步 master 停在 226c33893,而 master 之后又走了 release-v0.1.209([PR] release v0.1.209 #4982)、windows-latest CI will always be red: the drain e2e in #4982 uses POSIX-only kill(SIGTERM) to trigger graceful shutdow | windows-latest CI 必红:#4982 的 drain e2e 用 POSIX 专属的 kill(SIGTERM) 触发优雅退出,Node 在 Windows 上是直接硬杀 #5050 测试修复、[PR] ci: 恢复紧急快速发布入口(fast 模式加双信号防误触门) #5054。
  2. 什么原因导致的: 常规版本漂移。全树逐 blob 三方比对(1899 个文件):9 个文件只有 master 动过、15 个只有本分支动过,均无歧义;真正的文本冲突只有 1 个——tests/issue4982-draining-twin-ladder.test.ts(master 侧 windows-latest CI will always be red: the drain e2e in #4982 uses POSIX-only kill(SIGTERM) to trigger graceful shutdow | windows-latest CI 必红:#4982 的 drain e2e 用 POSIX 专属的 kill(SIGTERM) 触发优雅退出,Node 在 Windows 上是直接硬杀 #5050 的跨平台 shutdown 修复 vs 分支侧的 fixture 重构,两边改了同一段)。
  3. 影响范围与严重程度: 仅影响该 PR 本身,不改变任何产品行为;不解决则 PR 无法合并。
  4. 怎么修复的: merge master → 分支,唯一冲突按「intent union」裁决:①分支的 silentTcpListener() Promise 封装、abort-probe 新用例、killChild() 定时器+close 重构全部保留;②master 更新的全平台 POST /__bili/shutdown 优雅退出路径(含 held.on("error") 守卫、等待预算 20s→30s)整体采纳,替代分支里 win32-only 的旧变体(master 版是后来针对 windows-latest CI will always be red: the drain e2e in #4982 uses POSIX-only kill(SIGTERM) to trigger graceful shutdow | windows-latest CI 必红:#4982 的 drain e2e 用 POSIX 专属的 kill(SIGTERM) 触发优雅退出,Node 在 Windows 上是直接硬杀 #5050/安装新版本后旧代理永远不换新:detach 代理躲过应用退出,重启只是重新挂上旧进程(「永远更新不了」) #3544 专门设计的跨平台接缝,覆盖分支方案);③fixture 同时保留两边的 socket error 监听(RST 兜底 + destroy)。合并后文件已验证:相对 master 只差分支侧改动,相对 PR 只差 master 侧 3 处 hunk。
  5. 是否有回归问题: 无意外回归——9 个取自 master 的文件与 master 逐字节一致,15 个分支文件原样保留,冲突文件两侧内容各自都是 CI 已绿的版本。一处有意的测试面行为变更(继承自 master windows-latest CI will always be red: the drain e2e in #4982 uses POSIX-only kill(SIGTERM) to trigger graceful shutdow | windows-latest CI 必红:#4982 的 drain e2e 用 POSIX 专属的 kill(SIGTERM) 触发优雅退出,Node 在 Windows 上是直接硬杀 #5050,非本次引入):该 e2e 在 POSIX 上也改用 HTTP /__bili/shutdown 驱动 P1 退出(原来是 SIGTERM),等待预算 20s→30s。
  6. 是否破坏缓存: 不涉及。
  7. 是否改了设计方向: 不涉及。
  8. 是否引入了新的配置: 不涉及。

交付: z0d0dOr:2026-10-25_bounded-session-load 现为 46ad1110fde0db6b2de710bcf83cbba4341f8593(parents = PR 旧 head + master tip),PR 状态 mergeable=true,CI 绿,可以走人工合并了。

@ranxianglei

Copy link
Copy Markdown
Owner

🤖 Powered by ework · qwen3.8-27b

[bot] (ai: vllm-qwen/qwen3.8-27b)

状态确认(进程曾被看门狗重启,现复核完毕):冲突修复已完成并推送,无阻塞。

  • 分支 z0d0dOr:2026-10-25_bounded-session-load 已合入 master(merge commit 46ad1110f,非 rebase),唯一冲突文件 tests/issue4982-draining-twin-ladder.test.ts 按两侧意图并集解决;
  • 刚复核:PR 仍为 open、mergeable=true、head=46ad1110f,CI 30 项检查 0 失败 0 待跑;
  • 详细八问见上一条 [bot] 评论。可走人工合并。

@ranxianglei

Copy link
Copy Markdown
Owner

🤖 Powered by ework · qwen3.8-27b

(ai: vllm-qwen/qwen3.8-27b)

已把最新 origin/master(09a5b5b)合入分支并推送——干净合并、无冲突;PR head 现为 911c776,mergeable=true,状态由 behind 转为 blocked(仅等待新 head 上已排队的 23 项 CI 检查)。

@ranxianglei

Copy link
Copy Markdown
Owner

🤖 Powered by ework · qwen3.8-27b

(ai: vllm-qwen/qwen3.8-27b)

CI 失败诊断(自动修复车道 attempt 2/2)——结论:继承性 flake,非本 PR 引入,本分支无可修点,已归口 #4599;需 admin 重跑或等哨兵 ci-fixes→master。

结构化八问

  1. 是什么问题:head 911c776 上 3 个 test 分片(ubuntu 22 s3 / windows 22 s4 / ubuntu 24 s3)各挂且三处逐字同一用例:not ok … - HTTP a cold-restored non-retained parent serves its intact raw tail immediately (#5140) @ tests/plugin-fork.test.ts:1473:16,strictEqual: 409 !== 200(期望 200 实得 409)。每片其余全绿(u22/u24 各 3440 pass、win22 2531 pass,各自 fail 1)。
  2. 什么原因导致的:这是 master 侧 [PR] fix: recover non-retained parent fork snapshot from intact unified raw tail after cold restart (#5140) #5144(cold raw-tail fork,10-29 合入)引入的负载时序 flake,与本 PR 无关。证据链:①本 PR 的 base 就是 master 09a5b5b7,而该 sha 自身带此同一签名失败,CI Control Center: Centralized CI Failure Handling & Status Sync (Comment all CI issues here; do not open new issues) | CI 总控: CI 失败集中处理与状态同步(所有 CI 问题在此评论, 勿开新 issue) #4599 上一条(Louie0806 判 [Bug] Drifted open-tag names (acpt/acct/accent…) and mid-text draft envelopes reach the client verbatim — two thinking-leak shapes #5175/[PR] fix(#5175): strip drifted open-tag names and mid-turn draft envelopes #5178)已实证 09a5b5b7 同时存在 8-red 与多份全绿 run = 阵发;②最新哨兵状态(00:17Z)确认 master 此刻就在这些 shard 上红,修复正收敛到常驻 ci-fixes;③本 PR 对 tests/plugin-fork.test.ts 唯一改动是第 118 行 1 处 Windows teardown 微调(store.cancelAll()→store.closeQuietly(),修 Windows 临时目录清理,不碰 [Bug][fork] Cold restore cannot use an intact unified raw tail for a non-retained parent (#4266 item 4) #5140 冷恢复路径),而 base 09a5b5b7(仍 cancelAll)不带此改动也同红 —— A/B 排除本 PR 因果。
  3. 影响范围与严重程度:与本 PR 功能(限会话加载内存 + 窄读 lazy 字段)零关联;受影响面 = 所有基于 ≥[PR] fix: recover non-retained parent fork snapshot from intact unified raw tail after cold restart (#5140) #5144 的 PR 在同 shard 组合下的偶发 CI 红,非用户可见缺陷。对本 PR 正确性无影响(其存储自测在本 head 全绿,前几轮 review 已逐项过回归)。
  4. 怎么处理的(为何不在本分支改):按 CI 协调政策(owner 2026-10-24)——master 级继承红禁止在单 PR 分支重复修,修复必须收敛到 ci-fixes(哨兵统一维护)。核对 git merge origin/ci-fixes:ci-fixes tip cf99d935f 已是本 head 祖先(本 PR 早前已合),merge=Already up to date,无新内容可合;[PR] fix: recover non-retained parent fork snapshot from intact unified raw tail after cold restart (#5140) #5144 的加固又尚未落到 ci-fixes(哨兵刚接管)。故本分支既无可合新修复、也无落自己因果路径内的小改;强行去动 plugin-fork.test.ts 冷恢复逻辑 = 越界改 master 级代码,违规。
  5. 是否有回归问题:无。本 PR 未引入任何新失败(3 片签名与 master base 逐字一致且为已知 flake);本 PR 触达路径(persist/storage/bounded-load/lazy-narrow-reads 自测)在本 head 全过。
  6. 是否破坏缓存:不涉及。
  7. 是否改了设计方向:不涉及。
  8. 是否引入了新的配置:不涉及。

下一步(均在本 agent 权限外,不再自行长查继承红):①admin 重跑 run 40911468467 的 3 个失败 job(flake 大概率转绿);或 ②等哨兵把 #5144 隔离加固收敛进 ci-fixes→master 后本 PR 自然转绿。代码层面本 PR 早已 review 通过(方向正确、回归审计干净),除这条继承性 flake 外无阻塞,转绿后即可走人工合并。已在 #4599 留一行归口记录。

@ranxianglei
ranxianglei merged commit 41d4680 into ranxianglei:master Oct 30, 2026
40 of 51 checks passed
Louie0806 pushed a commit to Louie0806/billion-context that referenced this pull request Oct 30, 2026
ranxianglei#4538: sampled read-back verification in bounded batches of 32 (headers
separately, blocks in persisted order, message hydration only at the
verifier's pointer seqs); sync and async share one code path; SQLite and
MySQL get bounded LIMIT/OFFSET + seq-IN reads.

Conflict resolutions (p4540 base is pre-ranxianglei#5193/ranxianglei#4765/ranxianglei#4750; our side is the
superset in every region):
- src/storage/backend.ts: keep ours — p4540 added no content beyond ours
  (its sessionViewRows/readSnapshot/StorageReadView surface already present
  from ranxianglei#4765/ranxianglei#4750 merges); verified diff shows zero theirs-only lines.
- src/storage/store.ts: union — p4540's getBlocks 'ORDER BY ord, block_id'
  total ordering (stable pagination across generations) onto our gc()
  batch-sweep constants, viewPointerSeqs, readSnapshot/readSnapshotAsync,
  activeForeignWriter, formatDbSize; comment kept ours' pluginSnapshotSeqs
  wording (documents the live field shape).
- src/storage/mysql.ts: union — p4540's dedicated-pool reads with
  hydrateMediaAsync(conn) parameterization onto our v9 stamp +
  idx_content_refcount probe block + collectZeroRefIn lifecycle scoping;
  theirs-only lines audited line-by-line: all stale base versions of code
  our branch already carries (ranxianglei#5193 master state).
- tests/plugin-fork.test.ts: keep ours' longer ranxianglei#4599 comment,
  replicasAvailable() gate (supersedes theirs' storageMode==="full"), and
  ours' ranxianglei#5140 raw-tail cold-restart test semantics (200, not 409); p4540's
  storageMode loop + env save/restore already on our side via ranxianglei#4765.
- tests/storage-orphan-recovery.test.ts: take p4540's extra assert
  (alignedRef === "m00001") — pure addition, variable already defined.
Louie0806 pushed a commit to Louie0806/billion-context that referenced this pull request Oct 30, 2026
…anxianglei#4765/ranxianglei#4750

The two PRs added different getBlockContents call shapes (paged rows for
bounded view decode vs full narrow contents map for lazy-field restore);
merged as one union return type, which broke caller-side narrowing in the
read-snapshot test. Declare the overload pair so paged callers get the row
array and no-arg callers get the map. storage-bounded-load's read counter
monkey-patch now casts to the implementation signature it already matches
at runtime (every counted call passes opts.limit=32).
@github-actions github-actions Bot mentioned this pull request Oct 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working p1 scope/storage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: bound ordinary session loading and avoid full reloads for lazy fields

2 participants