# 2026-06-08 — server_batch 僵尸回收与 stuck 扫描

## 背景

部署/API 重启后，批量任务 asyncio 协程丢失，Redis/MySQL 仍保持 `running`（例：任务 #20）。脚本执行已有 `detect_stuck_executions`，批量任务缺失对等机制。

## 方案

1. **启动回收（#1）**：primary worker `lifespan` 在 Redis 就绪后调用 `recover_orphaned_batch_jobs()`，扫描 Redis `server_batch:*` 与 MySQL `status=running`，将未完成服务器标为失败（「服务重启导致任务中断」），`finalize` 并落库/审计。
2. **周期 stuck（#2）**：`server_batch_reconcile_loop` 每 60s 调用 `detect_stuck_batch_jobs()`，`updated_at` 超过 1h 的 `running` 任务自动收尾（「执行超时无响应」）。

## 涉及文件

- `server/infrastructure/redis/server_batch_store.py`
- `server/infrastructure/database/server_batch_job_repo.py`
- `server/application/services/server_batch_service.py`
- `server/background/server_batch_reconcile.py`
- `server/main.py`

## 测试

```bash
pytest tests/test_server_batch_reconcile.py -q
bash scripts/local_verify.sh
```

## 回滚

移除 `main.py` 启动/后台任务接线；已 finalize 的任务不可自动恢复。
