fix(automation): 启动时收尾卡在 running 的运行记录
作业是在调度线程里同步跑的:进程一重启(部署、崩溃、手工重启),那一轮就再没 机会写回结果,automation_runs 会永远停在 running,页面上一直显示「执行中」。 登录任务早有孤儿清理,运行记录原先漏了。 线上就是这么暴露的:部署时重建容器打断了正在跑的 ck_relogin 第 14 轮,重启清理 把 20 个在途账号标成了「重新登录中断(旧 Cookie 已保留)」(这部分是对的), 但 run 14 本身永远卡在 running,detail 为空。 新增 cleanup_orphan_runs(),在启动清理链里调用:把所有 running 的运行记录收尾为 failed + finished_at + 「服务重启中断」。如实记为 failed 而不是 success —— 那轮 确实没跑完;被中断的账号由各自的孤儿清理负责标记并按退避重试。 新增回归测试:只有 running 的被收尾,已完成的不受影响。 (另一件事一并说明:上一次部署我报告「零中断」是验证过早 —— 检查时部署的 up -d 还没执行到。实际情况是 mysql 未被重建(达到了本次改动目的),但应用容器因镜像 变化被正常重建,因此打断了那轮重登。)
This commit is contained in:
@@ -66,6 +66,11 @@ async def lifespan(app: FastAPI):
|
||||
cleaned_relogin = cleanup_orphan_relogin_tasks(db)
|
||||
if cleaned_relogin:
|
||||
logger.info(f"启动清理 CK 重登残留任务: {cleaned_relogin} 条")
|
||||
from .services.automation.scheduler import cleanup_orphan_runs
|
||||
|
||||
cleaned_runs = cleanup_orphan_runs(db)
|
||||
if cleaned_runs:
|
||||
logger.info(f"启动收尾中断的自动化运行记录: {cleaned_runs} 条")
|
||||
cleaned_login = cleanup_orphan_login_tasks(db)
|
||||
if cleaned_login:
|
||||
logger.info(f"启动清理登录残留任务: {cleaned_login} 条")
|
||||
|
||||
@@ -118,6 +118,26 @@ def _due(job: AutomationJob, now: datetime) -> bool:
|
||||
return next_run_at is None or next_run_at <= now
|
||||
|
||||
|
||||
def cleanup_orphan_runs(db: Session, message: str = "服务重启中断") -> int:
|
||||
"""把上次进程留下的 ``running`` 运行记录收尾。
|
||||
|
||||
作业是在调度线程里同步跑的:进程一重启(部署、崩溃、手工重启),那轮作业就
|
||||
再没机会写回结果,``automation_runs`` 会永远停在 ``running``,页面上一直显示
|
||||
「执行中」。登录任务有自己的孤儿清理,运行记录原先漏了。
|
||||
|
||||
收尾为 ``failed`` 而不是 ``success``:那轮确实没跑完,如实记录;被中断的账号
|
||||
由各自的孤儿清理负责标记,并会按退避重试。
|
||||
"""
|
||||
orphans = db.query(AutomationRun).filter(AutomationRun.status == "running").all()
|
||||
for run in orphans:
|
||||
run.status = "failed"
|
||||
run.finished_at = datetime.now(UTC)
|
||||
run.message = message
|
||||
if orphans:
|
||||
db.commit()
|
||||
return len(orphans)
|
||||
|
||||
|
||||
def run_due_jobs(db: Session, *, now: datetime | None = None) -> list[dict[str, Any]]:
|
||||
"""跑一轮「到点的作业」,返回每轮结果。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user