Files
gongxue-base/docs/refactor/import-worker-lease-verification.md
2026-07-12 19:26:57 +08:00

43 lines
2.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Import worker 持久 lease 验证报告
更新时间2026-07-12
## 结论
`content_import_jobs` 已具备多实例和进程重启所需的持久 lease 与 fencing 语义。验证只在专用测试库 `127.0.0.1:55432` 执行,没有连接生产环境。
## 实现边界
- migration `202607120016_content_import_job_leases.sql` 增加 `lease_token``lease_expires_at``last_heartbeat_at`、一致性约束和 pending/expired 部分索引。
- claim 使用原子 `SKIP LOCKED`,可同时领取 ready pending job 和 lease 已过期的 importing job。
- 每次 claim 只增加一次 `attempt_count` 并生成新 token失败调度只写 `next_attempt_at`,不会重复增加 attempt。
- worker 在执行期间续租;续租、完成、失败和重试都要求 token 匹配且 lease 未过期。
- API executor 的业务写入和终态更新处于同一事务。fencing 校验失败会回滚题目、版本、集合绑定、item 和 audit 写入。
- 最后一次 attempt 的 lease 过期后由 claim/reaper 路径直接标记 failed避免第 `max_attempts + 1` 次执行。
## 动态覆盖
`scripts/import-worker-integration-test.js` 在 destructive-test database guard 后验证:
1. 两个并发 worker 对三个 job 原子 claim没有重复领取。
2. 心跳推进 `last_heartbeat_at` 并延长 `lease_expires_at`
3. 模拟崩溃后,过期 job 被新 worker 接管token 旋转且 attempt 从 1 变为 2。
4. 旧 token 的执行在业务写入前被拒绝,旧 token 的失败提交也不能覆盖新 lease。
5. 新 lease 可完成 job终态清空 lease 字段并保持准确 attempt。
6. retry 保持 pending、持久 `next_attempt_at`,再次 claim 才增加 attempt。
7. 最后 attempt 过期后进入 failed不再重新执行。
## 验证命令
```bash
npm run check:worker
npm run check:api
npm run build:worker
DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:55432/postgres \
node scripts/import-worker-integration-test.js \
--confirm=SMOKE_SEED_LOCAL_OR_CI_ONLY
node scripts/production-readiness-check-test.js
```
完整 worker integration 会先跑 smoke seed执行时必须明确指向允许 destructive tests 的本地/CI 数据库。