perf(scale): 50k 压测 harness + resume 计数与 CI artifact 修复 - #3
Conversation
- perf_scale.rs: --start-doc 断点续跑参数(50k 压测期间遗留未提交) - perf_scale.rs: --max-contention-factor 断言,超标非零退出(供 CI 门槛,目标小于 2x) - 新增 .github/workflows/perf-scale.yml:手动触发 + 每周日 02:34 UTC 全量 50k,报告 JSON 上传 artifact - README/PERF_SCALE_50K.md:同步 50k 验证结论与 CI 复跑说明
resume 场景下 --start-doc 可能早于实际进度,重复写入的文档会替换旧 chunk,原实现用'库里已有数 + 本次写入数'累加会重复计数、虚报 indexed_chunks 与 chunks/s;改为以 DB 实际 chunk 数为准。 CI 侧给 artifact 上传加 if: always():断言失败时才是最需要报告的时候,原来恰好在那时丢掉报告。
当前 workspace/UI/Tauri 版本均为 1.5.2,但 docs/release 只有到 v1.5.0,lint job 的版本一致性检查因此必然失败(上游 collab 本身也缺)。补齐 RELEASE_NOTES_v1.5.2.md,覆盖本次工程硬化与 OCR 变更、已知边界与升级说明。 同时把 docs/README.md 的 Release 索引补上 v1.5.0 与 v1.5.2 两条(此前 v1.5.0 也未登记)。
审查者指南本 PR 建立了可手动或定时复跑的 50k 压测 CI,并在 harness 中加入断点续跑、真实 chunk 计数和争用系数断言;同时修复失败时报告 artifact 丢失问题,补充规模验证文档及 1.5.2 release notes 以完成文档和版本一致性。 可恢复性能规模索引与报告的时序图sequenceDiagram
participant CI as PerfScaleCI
participant Harness as perf_scale
participant Store as VectorStore
participant DB as SQLiteDB
CI->>Harness: Run with --start-doc and --report
alt start_doc == 0
Harness->>Store: purge_all_index_data()
Harness->>Store: begin_full_rebuild()
else start_doc > 0
Harness->>Harness: seed_corpus(start_doc)
end
loop documents from start_doc to docs
Harness->>Store: index document chunks
Store->>DB: replace existing chunks
end
Harness->>Store: finish_full_rebuild()
Harness->>Store: load_from_db()
Store->>DB: count_chunks()
DB-->>Harness: actual chunk count
Harness->>Harness: write report with indexed_chunks
Harness-->>CI: contention assertion result
性能规模 CI 断言与 artifact 保留流程图flowchart TD
A[workflow_dispatch or weekly schedule] --> B[Run perf_scale with 50k defaults]
B --> C{contention_factor <= max limit?}
C -->|Yes| D[Process succeeds]
C -->|No| E[Process exits nonzero]
D --> F[Upload perf_scale_ci_report.json]
E --> F
F --> G[Artifact available for PASS or FAIL run]
文件级变更
提示与命令与 Sourcery 交互
自定义使用体验访问你的控制面板:
获取帮助Original review guide in EnglishReviewer's Guide本 PR 建立了可手动或定时复跑的 50k 压测 CI,并在 harness 中加入断点续跑、真实 chunk 计数和争用系数断言;同时修复失败时报告 artifact 丢失问题,补充规模验证文档及 1.5.2 release notes 以完成文档和版本一致性。 Sequence diagram for resumable perf-scale indexing and reportingsequenceDiagram
participant CI as PerfScaleCI
participant Harness as perf_scale
participant Store as VectorStore
participant DB as SQLiteDB
CI->>Harness: Run with --start-doc and --report
alt start_doc == 0
Harness->>Store: purge_all_index_data()
Harness->>Store: begin_full_rebuild()
else start_doc > 0
Harness->>Harness: seed_corpus(start_doc)
end
loop documents from start_doc to docs
Harness->>Store: index document chunks
Store->>DB: replace existing chunks
end
Harness->>Store: finish_full_rebuild()
Harness->>Store: load_from_db()
Store->>DB: count_chunks()
DB-->>Harness: actual chunk count
Harness->>Harness: write report with indexed_chunks
Harness-->>CI: contention assertion result
Flow diagram for perf-scale CI assertions and artifact preservationflowchart TD
A[workflow_dispatch or weekly schedule] --> B[Run perf_scale with 50k defaults]
B --> C{contention_factor <= max limit?}
C -->|Yes| D[Process succeeds]
C -->|No| E[Process exits nonzero]
D --> F[Upload perf_scale_ci_report.json]
E --> F
F --> G[Artifact available for PASS or FAIL run]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
您好——我发现了 1 个问题
面向 AI Agent 的提示
请处理此次代码审查中的评论:
## 各条评论
### 评论 1
<location path="memori-core/examples/perf_scale.rs" line_range="195-197" />
<code_context>
- // 干净起点:删除旧 DB。
- let _ = std::fs::remove_file(&args.db_path);
+ // 干净起点:删除旧 DB(--start-doc>0 续跑时保留)。
+ if args.start_doc == 0 {
+ let _ = std::fs::remove_file(&args.db_path);
+ }
if let Some(parent) = args.db_path.parent() {
std::fs::create_dir_all(parent)?;
</code_context>
<issue_to_address>
**问题 (bug_risk):** 当 `--start-doc` 大于零,但指定的数据库不存在时,代码会创建一个新的空数据库,并且只为 `start_doc..docs` 范围内的文档建立数据;此时,报告却声称包含完整的 `docs` 文档集,尽管前面的文档并不存在。
**触发条件:** 使用缺失、已删除或指定错误的 `--db-path` 开始续跑时。
**建议修复:** 除非数据库存在且包含预期的既有文档集,否则应立即失败;或者在继续之前,显式地为缺失的前缀文档建立数据。
</issue_to_address>Sourcery 评估
等待批准。 需要先处理 1 个发现的问题。
阻塞性发现:memori-core/examples/perf_scale.rs:197
Original comment in English
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="memori-core/examples/perf_scale.rs" line_range="195-197" />
<code_context>
- // 干净起点:删除旧 DB。
- let _ = std::fs::remove_file(&args.db_path);
+ // 干净起点:删除旧 DB(--start-doc>0 续跑时保留)。
+ if args.start_doc == 0 {
+ let _ = std::fs::remove_file(&args.db_path);
+ }
if let Some(parent) = args.db_path.parent() {
std::fs::create_dir_all(parent)?;
</code_context>
<issue_to_address>
**issue (bug_risk):** When `--start-doc` is greater than zero but the specified database does not already exist, the code creates a new empty database and seeds only documents in `start_doc..docs`; the report then claims the full `docs` corpus even though the earlier documents are absent.
**Triggers:** When a resume is started with a missing, deleted, or incorrectly specified `--db-path`.
**Suggested fix:** Fail fast unless the database exists and contains the expected prior corpus, or explicitly seed the missing prefix before continuing.
</issue_to_address>Sourcery assessment
Approval pending. 1 finding to address first.
Blocking findings: memori-core/examples/perf_scale.rs:197
| if args.start_doc == 0 { | ||
| let _ = std::fs::remove_file(&args.db_path); | ||
| } |
There was a problem hiding this comment.
问题 (bug_risk): 当 --start-doc 大于零,但指定的数据库不存在时,代码会创建一个新的空数据库,并且只为 start_doc..docs 范围内的文档建立数据;此时,报告却声称包含完整的 docs 文档集,尽管前面的文档并不存在。
触发条件: 使用缺失、已删除或指定错误的 --db-path 开始续跑时。
建议修复: 除非数据库存在且包含预期的既有文档集,否则应立即失败;或者在继续之前,显式地为缺失的前缀文档建立数据。
Original comment in English
issue (bug_risk): When --start-doc is greater than zero but the specified database does not already exist, the code creates a new empty database and seeds only documents in start_doc..docs; the report then claims the full docs corpus even though the earlier documents are absent.
Triggers: When a resume is started with a missing, deleted, or incorrectly specified --db-path.
Suggested fix: Fail fast unless the database exists and contains the expected prior corpus, or explicitly seed the missing prefix before continuing.
|
审过了,可以合。上一轮指出的两条都修对了,也都核实过:
其余部分(workflow 的手动输入 + 周期触发、 唯一一件事:请把 这份 release notes 在 #2 / #3 / #4 里完全相同(md5 一致),且写了 "adds OCR ingestion for images and scanned documents"。#4 的 OCR 还在返工(漏了间接 摘掉之后就可以合了。 |
|
复审通过,可以合了。
前一轮的两条修复维持不变,再确认一次:
无新增意见。 |
合并 FPSZ#2/FPSZ#3/FPSZ#5 后的 collab,三处冲突均为双方各自新增内容,保留双方: - README.md「已实现但仍在优化」:50k 压测条目 + OCR 条目 - docs/qa/RETRIEVAL_BASELINE_V2.md:作答层 LLM-judge 基线 + OCR 接入与边界 - memori-server/src/dto.rs:AppSettings 的 index_filter 与 ocr_tesseract_path 两个字段 同时启用 pdf_with_indirect_resources_is_extracted(原 #[ignore]): 手工构造 lopdf::Stream 用结构体字面量会绕过 /Length 写入(lopdf object.rs:602 的 Stream::new 才会 dict.set("Length", ...)),存盘后流长度为 0、load 回来 content 为空,解码拿不到像素,测试因此假失败——与 get_pages() 无关(实测 get_pages()=1、get_page_resources 也正确返回 inherited)。改用 Stream::new 后 测试通过,可作为间接 /Resources + 间接 /XObject 的回归锁。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
背景
评审对压测部分只提了两条:
if: always()与 resume 计数。本 PR 把压测 harness 与这两处修复放在一起。包含内容(3 个提交)
perf(scale): 压测 harness 支持续跑与断言,新增 50k CI 复跑 workflow(原提交)perf(scale): 修复压测 harness 的 resume 重复计数与 CI artifact 上传--start-doc早于实际进度时,重复写入的文档会替换旧 chunk;原实现用"库里已有数 + 本次写入数"累加 → 重复计数、虚报indexed_chunks与chunks/s。现改为以 DB 实际 chunk 数为准。if: always():断言失败时才是最需要看报告的时候,原来恰好在那时丢掉 artifact。docs(release): 补齐 1.5.2 release notes 与文档索引—— 让 lint 的版本一致性检查能过(原因同 PR ①)验证
cargo test --workspace --all-targets全绿,0 失败collab最新050c690,behind_by=0Sourcery 总结
新增可恢复的 5 万规模性能验证,提供可靠的指标、即使失败也能保留的报告,以及更新后的发布文档。
新功能:
错误修复:
增强功能:
CI:
文档:
Original summary in English
Sourcery 总结
建立可恢复的 5 万规模性能验证机制,提供可靠的指标、在失败时保留报告的 CI,以及一致的发布文档。
新功能:
错误修复:
增强功能:
CI:
文档:
Original summary in English
Summary by Sourcery
Establish resumable 50k-scale performance validation with reliable metrics, failure-preserving CI reports, and aligned release documentation.
New Features:
Bug Fixes:
Enhancements:
CI:
Documentation: