fix(session): cap summary.diffs at 256KB to stop event-loop starvation - #459
Merged
Conversation
chore: sync main back into dev after MCP v2 hardening deliveries
LeXwDeX
marked this pull request as ready for review
August 28, 2026 08:07
#434 after init --force)
… regex policy parse)
This was referenced Aug 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #458
Why
一次 upstream sync 会话把 37.8MB 全量 git diff 注入 user 消息
summary.diffs(实测message.data= 37,872,527 字节;event 表单条message.updated达 37.87MB,全局 opencode.db 被撑至 10GB)。此后每次updateMessage都把 37.8MB 写入 message 行 + event 表 + SSE 广播,同进程 TUI 处理巨型事件产生分配风暴(CPU ~142%、GC 满负荷、RSS 稳定 9GB),事件循环饿死导致 ESC abort 请求永远得不到调度——用户只能kill -9。会话全部 137 个 parts 仅 695KB:diffs 是纯元数据(TUI 展示用),截断不影响发给 LLM 的内容。What changed
三层防护,共享常量
MAX_SUMMARY_DIFF_BYTES = 256KB(packages/opencode/src/session/session.ts):src/session/summary.tssummarizecomputeDiff之后、updateMessage之前按贪心字节预算保留前缀文件列表,新数据不再超限session.tsfromRow/stripOversizedDiffssummary_diffs整体剥离,保留 additions/deletions/files 统计——已存在的 37.8MB 旧消息重新加载即被卸载,旧会话可安全继续session.tstoRow/truncateSummaryDiffssummary_diffs均不超预算字节记账精确(
[]括号 2 字节、逗号 +1),写/读护栏互补,round-trip 幂等无震荡。summary.ts复用session.ts导出的同一 helper,无循环依赖、无重复算法。Evidence
bun run typecheck(tsgo --noEmit)通过test/session/summary-diff-guard.test.ts:7/7 pass(真实服务图Session.node+ 真实Database.node,仅 stubSnapshot.diffFull)——源头截断保持前缀顺序且不超预算;读护栏剥离 legacy 超限行保留统计;预算内 round-trip 无损;空数组/单条超预算/精确满额三个边界bun run test:dag-core:52 pass / 0 fail(DAG 门禁无回归)Checklist
summary.diffs为undefined在 schema 与全部 TUI 消费方均为合法形态