Archived
This repository has been archived on 2026-10-02 . You can view files and clone it. You cannot open issues or pull requests or push a commit.
da83201403b50e6335eb43169feb2a540f9e9db0
为什么:run_zip_job 是全仓圈复杂度最高的函数(37),167 行里四个终态——正常交付、
全部失败、取消(含部分交付/全额退两条支路)、异常(同样两条支路)——各写一段
8~20 行的收尾内联在 try/except 里,且都伸手去读同一批局部变量。上一轮抽这个引擎时
就已指出「还可以再拆」,当时为控制单次改动面留了下来。
改法:把「一次运行」的状态收进 _ZipRun,四个终态各自成函数。
_ZipRun job / task_id / settle / tally / task / params /
cancel_ev / pause_ev / items / zip_tmp_path / zip_valid / t0
_progress_of 构造进度回调(原先是个内嵌闭包)
_start_zip_run 置 running + 组装清单 + 写 total + 计费补扣
_build_zip_archive 建临时 ZIP + 逐窗口填充 + 置 zip_valid + 记耗时
_publish_delivery 正常交付(结算 → 锁内复查 → 发布 result → on_delivered → 日志)
_finish_all_failed 全失败(丢弃空包 + 全额退费 + 转 error)
_finish_canceled 取消(部分交付 / 全额退两条支路)
_finish_business_error DownloadException(保留我们自己拼的用户可读文案)
_finish_unexpected 通用异常(先落 traceback 再泛化文案,两条支路)
复杂度(同口径 AST 实测,HEAD 与工作区由同一脚本测出):
run_zip_job 167 行 / 圈 37 / 嵌套 4 → 32 行 / 圈 5 / 嵌套 2
文件内最大圈复杂度 37(就是它) → 13(_fill_zip,本次未动)
文件行数 439 → 522(+83,全是新签名与 docstring)· 函数数 19 → 27
顺手消掉一个**隐患**,不是纯搬家:``zip_valid`` 原先必须手工在函数头初始化为
False(注释写明「漏了就 NameError 二次崩线程」——它正是上上轮那个 bug 的残留
护栏)。收进 dataclass 后该约束由构造函数承担,而 ``_ZipRun(...)`` 的默认值就是
假值,物理上写不出「忘记初始化」。
等价性证据(两道,互相独立):
1. 不靠注入脚本,直接把文件还原成 HEAD 版跑同一套测试(git stash push 单文件 →
跑 → pop):tests/test_zip_workers.py + test_monitor_jobs.py 共 33 例**全过**。
这批测试是上一轮用反向注入验证过「忠实编码旧行为」的,故本轮它们对新实现
构成等价性验证。
2. AST 字面量多重集比对:字符串 56 种**一个不少**——没有任何用户可见文案或日志
格式被动过。数值唯一差异是 `0.0: 0 → 1`,即 _ZipRun.t0 的字段默认值。
刻意保留的语义(是决定,不是疏漏):
- _publish_delivery 里「先 settle 再抛 DownloadCanceled」的顺序原样——抛出去后
_finish_canceled 会**再 settle 一次**(delivered 口径不同),依赖的是 ledger_settle
幂等;原实现同样如此,未动。
- 取消与异常两条支路里「部分交付」与「全额退」的判定条件(`delivered > 0 and
zip_tmp_path`)逐字保留。
- _finish_all_failed 不走 _apply_error:它要额外记 failed 计数,口径与 error 支路
不同(原实现即如此)。
- record_duration 仍在 zip_valid 置位之后、全失败判定之前(保持原顺序)。
验证:ruff 全过 · pyright 0/0 · pytest 294 passed(与改动前同数)· 生产 data/ 未被
触碰(全部用例走 tmp_path 沙箱)。
Languages
Python
61%
TypeScript
32.2%
CSS
6.6%
Dockerfile
0.1%