Skip to content

【架构优化】从 SaveWorkspaceCheckpointStream 中拆出分片暂存写入 stageWorkspaceCheckpointChunks - #749

Open
fx-kurumi wants to merge 2 commits into
mainfrom
refactor/checkpoint-stage-chunks-748
Open

fx-kurumi wants to merge 2 commits into
mainfrom
refactor/checkpoint-stage-chunks-748

Conversation

@fx-kurumi

Copy link
Copy Markdown
Collaborator

Closes #748

改了什么

  • internal/repo/workspace_checkpoint_chunks.go:把 RunsRepo.SaveWorkspaceCheckpointStream 里约 30 行的分片写入循环原样抽成私有方法 stageWorkspaceCheckpointChunks(runID, token, archiveID, source) (size, count, sum, err)。循环体(按 4 MiB 读块、512 MiB 上限报错、每块前校验租约、写分片行、累计 SHA-256)逐行不变,只是把局部变量 hash 改名 digest,不再遮蔽同文件导入的 hash 包。
  • SaveWorkspaceCheckpointStream 现在只剩:小归档走内联保存 → 生成 archive id 与失败清理 → 清理过期暂存分片 → 调用暂存 → 空归档判断 → 事务内按租约 CAS 发布清单。
  • 新增 internal/repo/workspace_checkpoint_stage_test.go,直接覆盖新方法。

为什么

原函数约 80 行,「暂存分片」和「发布清单」两个阶段混在一起,循环还要维护 size/count/hash 三个外层变量。拆开后两个阶段边界清楚,暂存逻辑也能单独测试。

影响范围

只在一个文件内做私有拆分。导出方法签名、SQL 条件、写入顺序、报错文案都没变,失败时 defer 清理暂存分片的逻辑也没变;调用方 internal/engine/workspace_checkpoint_stream.go 不用改。

怎么验证的

  • go vet ./internal/repo/ ./internal/engine/:通过
  • go test ./internal/repo/ -count=1 -cover:通过(coverage 77.6%),包括原有的 TestWorkspaceCheckpointChunksAtomicRoundTrip 等检查点用例
  • 新增 TestStageWorkspaceCheckpointChunks 的 5 个子用例:多块写入(字节数、块数、摘要正确,每行 ≤ 4 MiB,能拼回原数据)、恰好一块、空输入、租约失效返回 ErrWorkspaceInUse 且不留下分片行、读错误透传
  • 说明:go build ./... 在 web/embed.go 处失败,原因是缺少前端构建产物(native-chat)。不带本改动的 main 上同样失败,和这次改动无关。

🤖 Generated with Claude Code

fx-kurumi and others added 2 commits November 14, 2026 13:45
…intChunks

Closes #748

Co-Authored-By: Claude Code <noreply@anthropic.com>
…hunks

Co-Authored-By: Claude Code <noreply@anthropic.com>
@fx-kurumi

Copy link
Copy Markdown
Collaborator Author

补测试(针对 head f9a131c):推送 8236947,只新增 internal/repo/workspace_checkpoint_stage_lease_guard_test.go,未改实现。

为什么补:对 stageWorkspaceCheckpointChunks 做了 8 处变异(go test ./internal/repo -run Checkpoint),PR 自带的 TestStageWorkspaceCheckpointChunks 能发现 6 处(吞读错误、sequence、digest、提前结束、archiveID、count)。发现不了的:

  • 租约只在第一行前检查(active != 1 && count == 0):函数注释写的是「re-checking the lease before every row」,但现有 stale lease 子测试在第一行前就失败,验证不到写到一半租约丢失的情况。
  • 512 MiB 上限 > 改 >=:需要真实写入 512 MiB 分片才能区分,单测成本过高,本次没测(这段是原样搬移的旧逻辑)。

新增测试 TestStageWorkspaceCheckpointChunksStopsWhenLeaseLostMidStream(2 个子测试):读完第一块后让租约 ① 过期 ② 被别的 token 接管,断言返回 ErrWorkspaceInUse,且只留下 sequence 0 那一行,不再写第二行。加上后上面第一种变异能被发现。

本地验证(Go 1.26.11):gofmt -l internal/repo 无输出;go vet ./internal/repo/ 通过;go test -count=1 ./internal/repo/ 整包通过。

@Yanami-2K Yanami-2K left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

对照 #748 核对:stageWorkspaceCheckpointChunks 逐行搬移了分片循环(按 workspaceCheckpointChunkBytes 读块、超限报同样的错、每行前校验租约、写行后累计 SHA-256),空归档判断和事务发布留在主函数,published 失败清理语义未变;hash 改名 digest 解决了包名遮蔽。测试断言了多块大小/块数/摘要与可重组、整块边界、空源、过期租约不写行,以及租约中途过期或被接管后停在第二行,CI 全部通过。workspace_checkpoint_chunks.go 与 stage 测试的 patch 末尾被截断。

@Yanami-2K Yanami-2K left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

更正:上一条 APPROVE 评审末尾的 sha 标记写错了,评审结论不变,实际审查的 head 为 8236947。

@fx-kurumi

Copy link
Copy Markdown
Collaborator Author

复审结论:✅ 通过(head 8236947d)

  • internal/repo/workspace_checkpoint_chunks.go 把分片写入抽成 stageWorkspaceCheckpointChunks,返回 size/count/sha256,发布仍由调用方在同一事务里按 lease CAS 完成。核对:每写一行前重新查 lease 的时机没变(保证丢失租约的写入者在下一行就停下);size > workspaceCheckpointArchiveBytes 的检查仍在累加后;io.ReadFull 的 EOF/ErrUnexpectedEOF 分支与 n==0 退出条件一致;size == 0 的错误仍由调用方抛;失败时 published=false 触发清理暂存行。切片 Data: buffer[:n] 每轮 Create 同步序列化,不存在复用覆盖问题。
  • 新增 workspace_checkpoint_stage_test.go(多分片、整分片边界、空源、过期租约、读错误)与逐行 lease 复查用例,断言具体。
  • 本机(Go 1.26.11):go vet ./internal/repo/ 通过;go test ./internal/repo/ -run 'TestStageWorkspaceCheckpoint|TestSaveWorkspaceCheckpoint' -count=1 ok。
  • CI 16 项全部通过。

没有发现问题。

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.

【架构优化】从 SaveWorkspaceCheckpointStream 中拆出分片暂存写入 stageWorkspaceCheckpointChunks

2 participants