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.
snowy-yang da83201403 refactor: run_zip_job 四路终态收尾拆解(167 行 / 圈 37 → 32 行 / 圈 5)
为什么: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 沙箱)。
2026-09-27 09:08:52 +08:00
S
Description
云村小助手 · 网易云音乐解析/下载服务(FastAPI + asyncio + aiohttp)
1.5 MiB
0 Stars 1 Watchers 0 Forks
Languages
Python 61%
TypeScript 32.2%
CSS 6.6%
Dockerfile 0.1%