refactor(subscribe): introduce candidate batch index

This commit is contained in:
jxxghp
2026-09-01 12:58:51 +08:00
parent 113ca6da92
commit 04ecfbd7f6
8 changed files with 603 additions and 146 deletions

View File

@@ -1,7 +1,7 @@
# MoviePilot 订阅执行治理
> 状态:`active(2026-09-01 已由 MoviePilot v3 接管)`
> 当前叶:`SUB-GOV-001B`
> 当前叶:`SUB-GOV-001C`
> 迁移来源:`V3-RDY-009A`、`V3-RDY-009A1`、`V3-RDY-009A1B`、
> `V3-RDY-009A1C`、`V3-RDY-009A1D`
> 适用范围:V3 订阅刷新、匹配、兜底搜索、下载提交与用户状态闭环
@@ -228,8 +228,8 @@ RSS/Spider 保持现有逐站点串行刷新,不通过并发化换取几秒收
| --- | --- | --- | --- |
| `SUB-GOV-000` | 固定历史行为和生产日志;保留 `V3-RDY-009A1A` 已交付的批量请求正确性 | 无 | `completed` |
| `SUB-GOV-001A` | 建立日常 Match 正确性和可重放夹具;撤销 `cache=True` 错误候选,只保留经验证不改变语义的失败识别状态回写 | 000 | `completed(2026-09-01)` |
| `SUB-GOV-001B` | 区分完整缓存与本轮 delta,建立无损候选索引;先证明命中集合与基线完全一致 | 001A | `in_progress` |
| `SUB-GOV-001C` | 将资源匹配与完成对账拆开;只有受候选影响的订阅进入匹配,完成对账独立保持新鲜语义 | 001B | `pending` |
| `SUB-GOV-001B` | 区分完整缓存与本轮 delta,建立无损候选索引;先证明命中集合与基线完全一致 | 001A | `completed(2026-09-01)` |
| `SUB-GOV-001C` | 将资源匹配与完成对账拆开;只有受候选影响的订阅进入匹配,完成对账独立保持新鲜语义 | 001B | `in_progress` |
| `SUB-GOV-001D` | 引入单轮新鲜事实租约,评估稳定元数据复用、轻量季集查询和单媒体服务器事实合并 | 001C | `pending` |
| `SUB-GOV-001E` | 若 001B–D 后仍有可重复等待热点,再通过隔离压测评估 2/4 worker 的有界准备;提交保持串行 | 001D | `conditional` |
| `SUB-GOV-002A` | 将 24 小时兜底搜索移出 Match/提交长锁,建立批次、订阅 single-flight、可取消等待和恢复游标 | 001C | `pending` |
@@ -239,7 +239,7 @@ RSS/Spider 保持现有逐站点串行刷新,不通过并发化换取几秒收
| `SUB-GOV-003B` | 后端提供订阅及批次业务状态,前端展示排队、匹配、搜索、提交、完成、失败和取消 | 002A, 003A | `pending` |
| `SUB-GOV-004` | 多条订阅记录指向同一媒体时的跨记录季集去重和产品规则 | 003A | `pending(最低优先级)` |
当前只激活 `SUB-GOV-001B`。001B–D 是日常 Match 主线;002A–C 是 24 小时兜底搜索主线;003A/B
当前只激活 `SUB-GOV-001C`。001B–D 是日常 Match 主线;002A–C 是 24 小时兜底搜索主线;003A/B
只有在前两条链路的身份和终态稳定后实施。每个叶子完成验收并更新本表后,才激活下一个满足依赖的叶子。
### 6.1 SUB-GOV-001A 验收证据
@@ -253,6 +253,17 @@ RSS/Spider 保持现有逐站点串行刷新,不通过并发化换取几秒收
- 验证:上述重放、现有订阅 Chain 与候选筛选共 `118 passed`,固定 JSON、文档链接和
`git diff --check` 通过。
### 6.2 SUB-GOV-001B 验收证据
- `CandidateBatch` 同时表达完整缓存、本轮 `fresh_candidates`、预留 `retry_candidates`、来源、站点和批次时间;
- `TorrentsChain.refresh()` 保持原字典 ABI,新增 `refresh_batch()` 供订阅刷新消费,RSS/Spider 请求模型未改变;
- `CandidateIndex` 在一次构建后按媒体身份路由,并保持候选原顺序;未知身份、主识别失败、标题兜底、
自定义识别词和无显式标题 ID 的可复核冲突均进入保守集合;
- 严格缓存候选 API 委托新索引并继续返回深拷贝,插件可观察行为保持不变;
- 专项矩阵验证完整缓存与本轮 delta 分离,并验证索引只排除类型、季或显式身份上 canonical 必然拒绝的候选;
- 验证:订阅、候选、音乐缓存和架构测试共 `228 passed`,错误级 Pylint 为 0,
`scripts/architecture/baseline.py --check-host` 与 `git diff --check` 通过。
## 7. 上线前验证与验收
### 7.1 场景