Skip to content

fix: 报表口径三处对齐 + v0.2.2 文档补齐 - #8

Merged
mingyangbest merged 3 commits into
mainfrom
fix/reporting-and-docs
Nov 3, 2026
Merged

mingyangbest merged 3 commits into
mainfrom
fix/reporting-and-docs

Conversation

@mingyangbest

Copy link
Copy Markdown
Owner

这个 PR 做什么

一轮代码评审提了 8 组问题,这是其中「三个报表口径 bug + 文档滞后」的收口。修复、钉住 bug 的测试、文档三笔一个单元,不掺 workflow 和会话补测。

改动 4 个文件、+264/−9,app/engine.py 只有 24 行。

修的三个 bug

1. push 的哈希复核看错了对象(engine.py)

复核循环遍历的是 items(用户提交的文件全集),不是 uploaded(真上传成功的子集)。后果是上传失败的文件会拿本地内容去比云端的旧条目,报一个假的「内容哈希不符」,同时把 hashed 计数撑虚。

现在只复核 uploaded。另外补了 VERIFY_SHA256_MAX(64 MiB)截断——代码注释一直写着有上限,实际没有,大文件会把整份内容读进内存算哈希。

2. sync 报表把一个文件同时记成功和失败

原来是 ok_n = done_n、fail = fail + len(verify_bad)。上传成功但复核没过的文件,既算进成功数又算进失败数,报表上的总数对不上。

改成 ok_n = done_n - len(verify_bad)。

注意触发面:只在非凭证类失败时显现。凭证类失败会走补传分支,那里 failed.clear(); fail = 0,双计被重置掉了。

3. 推送侧云端索引没小写化

云端索引在 sync / collect 里都是 .lower() 建的,push 里用原始文件名去查。全是小写的文件名不会有事,一旦大小写不同就假报「云端未找到」。已统一成 .lower()。

测试:4 红 2 绿

tests/test_reporting.py 6 条,假云盘 + StubStore,不碰网络。

关键在这批测试跑在修复前的干净副本上是 4 红 2 绿:

  • 红的 4 条 = 四个 bug 真的被钉住了(ok_n=2 / fail=1 而目录里只有 2 个文件;假的「内容哈希不符」;超上限照比;A.TXT 报云端未找到)
  • 绿的 2 条 = 对照组,证明检查没被关掉

先写测试看它红、再改代码看它绿,这样测试才是在钉旧行为,而不是跟着实现写。

CI 三步本地复跑:compileall OK、pyflakes(含 tests/)OK、35 passed。

文档

  • CHANGELOG 新增 v0.2.2 一节,标注未发布
  • v0.2.1 里两处已被本次推翻的旧话加了注(不是删掉,留痕)
  • README 补「大文件断点续传」一节,含 TP_RESUME / TP_RESUME_MIN_SIZE 两个开关

顺带说明:v0.2.0 的 CHANGELOG 一直写着「续传没做、单测等收尾」,README 全文没有「续传」两个字——PR #7 把功能上了生产,文档没跟上。这次一并补掉。

刻意不做的

评审里另外几项,按「分开更好审」留给后续 PR:

项 为什么不在这
Runner.start 双跑竞态 两次持锁中间夹 db.start_run() 写,并发双跑会让第二条覆盖第一条的 RunState,症状是日志串台、停止按钮只停一条。改法是调整锁粒度,属运行时核心
/api/restore 并发守卫 比「没守卫」深一层:_REST 只有 jid 索引、没有 task_id 维度,连「同一任务已有恢复在跑」都查不出来。要加守卫得先补索引
push 空文件整批 fail-fast 和 sync 的空文件处理不一致,属行为变更
CI 启动冒烟 是 workflow 改动,能堵「构建成功但启动即崩」,单独一个 PR 更干净
全量重列云端树 唯一一条架构级天花板,成本最高,继续排后

within("")、orphans 递归深度、main.py 两处 db._conn() 越层、进程级 IPv4 monkeypatch 同样不动——都是只读或既有行为,不在补丁版范围内。

对生产的影响

无。这个 PR 只改 main 分支的代码与文档,不打 tag、不重建镜像。生产当前跑的是 b056bff2(代码 ef36741),与 main 的 f057a9d 一致,本 PR 不涉及它。

发版另开一步:tag 之前要先用 9–12 MB 真文件验证过一遍。

三处都是「传得上去、但账不对」的问题,不动主链路:

- 推送的哈希复核遍历的是 items(这次要推的全部文件),不是 uploaded
  (真正传成功的)。上传失败的文件会拿本地内容去和云端上一轮的旧条目比
  哈希,多出假的「内容哈希不符」,一致数也偏高。改成只复核 uploaded。
- 同上这段没有体积上限,注释却写着「仅对体积较小的文件」。补 VERIFY_SHA256_MAX
  (64MiB),与 sync 侧同一个常量、同一个口径。
- 推送的云端索引按原始大小写建键,而 sync 和孤儿扫描都按小写(云盘本身大小写
  不敏感)。云端回 IMG.JPG、本地叫 img.jpg 时会误报「云端未找到」并整轮判失败。
  统一小写。
- sync 的 ok_n 与 fail 会双计:一个文件上传成功但复核不通过,既进 done_n 又进
  verify_bad,报表上 ok_n + fail 大于实际文件数。改成 ok_n = done_n - len(verify_bad)。
新增 tests/test_reporting.py,用一个只记账的假云盘替掉网络层:

- sync:复核失败的文件只能算失败。旧代码上 ok_n=2 / fail=1(总数 3 > 文件 2)。
- push:上传失败的文件不参与哈希复核。旧代码会拿云端旧条目比出假的不符。
- push:超过 VERIFY_SHA256_MAX 只比体积。旧代码会照比不误。
- push:云端回小写、本地大写也能找到。旧代码报「云端未找到」。
- 对照两条:全部传对时口径不变;小文件哈希不符仍然要真报错。

在 HEAD(修复前)的干净副本上跑过:前 4 条红、后 2 条绿,说明这几条确实钉住了
改动的行为,而不是跟着实现一起写的「记得住答案」的测试。
- CHANGELOG 新增 v0.2.2(未发布):续传、35 项测试、这一轮四处口径修复,
  以及仍然没做的(本地索引 / IPv4 补丁 / db._conn 越层 / 全量 reload)。
- v0.2.1 那节里「续传没做」「单测等定案」两处是当时的记录,保留原文,
  加一句注明 v0.2.2 已补上,避免下次打 tag 时又把它当成现状。
- README:功能特性加一条断点续传,配置参考补 TP_RESUME / TP_RESUME_MIN_SIZE,
  使用里新增「大文件断点续传」一节——阈值、判废条件、24 小时 TTL、复核通过
  才删会话、以及 TP_RESUME=0 这个开关,用户以前只能从代码里看。
@mingyangbest
mingyangbest merged commit 13c43b0 into main Nov 3, 2026
2 checks passed
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.

1 participant