forked from wangziqi/gongxue-base
2.2 KiB
2.2 KiB
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 后验证:
- 两个并发 worker 对三个 job 原子 claim,没有重复领取。
- 心跳推进
last_heartbeat_at并延长lease_expires_at。 - 模拟崩溃后,过期 job 被新 worker 接管,token 旋转且 attempt 从 1 变为 2。
- 旧 token 的执行在业务写入前被拒绝,旧 token 的失败提交也不能覆盖新 lease。
- 新 lease 可完成 job,终态清空 lease 字段并保持准确 attempt。
- retry 保持 pending、持久
next_attempt_at,再次 claim 才增加 attempt。 - 最后 attempt 过期后进入 failed,不再重新执行。
验证命令
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 数据库。