优化脚本生成卡住问题

This commit is contained in:
Azmat@qq.com
2026-09-02 15:12:50 +08:00
parent c9522eea08
commit 22ed2833ad
5 changed files with 205 additions and 1 deletions
+54
View File
@@ -3409,6 +3409,60 @@ _STANDALONE_TASK_TYPE = {
}
# 脚本 agent 的 SSE 流是**在进程内跑的**(专业创作走 web 进程,一键成片走 worker 线程),
# 进程一没(部署滚动更新、OOM、Pod 驱逐),那条流就没了,但 AITask 行还停在 SUBMITTED,
# 预扣的积分也一直冻着 —— 任务监控里就是「进行中」挂几个小时不动。
# 图片有 _reap_stale_standalone_image_tasks、视频有 video_timeout_recovery,脚本此前是**裸奔**的。
# 单次脚本生成实测在秒~分钟级,20 分钟仍没终态一律判僵尸(quick_create 的 SCRIPT_TIMEOUT 是 30 分钟,
# 这里留足余量,先于它把行收干净,免得编排端一直等一个永远不会动的任务)。
SCRIPT_TASK_STALE_AFTER = timedelta(minutes=20)
_SCRIPT_TASK_TYPES = (AITask.Type.SCRIPT_GENERATION, AITask.Type.SCRIPT_OPTIMIZATION)
_SCRIPT_ACTIVE_STATUSES = (
AITask.Status.CREATED,
AITask.Status.RESERVED,
AITask.Status.SUBMITTED,
AITask.Status.POLLING,
AITask.Status.POSTPROCESSING,
)
def reap_stale_script_tasks(*, team=None, project=None) -> int:
"""回收被进程重启丢下的脚本任务:置 FAILED + 退还预扣积分。返回回收条数。
没有 celery beat,沿用本项目既有的「顺手回收」策略:每次新提交脚本、以及一键成片每轮推进时
各扫一次。这样存量僵尸行会在下一次生成时自愈,不需要人工进库改数据。"""
if team is None and project is None:
return 0
cutoff = timezone.now() - SCRIPT_TASK_STALE_AFTER
qs = AITask.objects.filter(
task_type__in=_SCRIPT_TASK_TYPES,
status__in=_SCRIPT_ACTIVE_STATUSES,
updated_at__lt=cutoff,
)
qs = qs.filter(project=project) if project is not None else qs.filter(team=team)
reaped = 0
for task in qs:
try:
with transaction.atomic():
task.status = AITask.Status.FAILED
task.error_message = "脚本生成进程中断(多为服务重启/部署),僵尸任务自动回收"
task.completed_at = timezone.now()
task.save(update_fields=["status", "error_message", "completed_at", "updated_at"])
try:
reservation = task.credit_reservation
except ObjectDoesNotExist:
reservation = None
if reservation is not None:
release_credit(reservation=reservation, reason="脚本任务僵尸回收")
reaped += 1
except Exception: # noqa: BLE001 — 回收是兜底,失败不该挡住正常生成
logger.warning("reap stale script task %s failed", task.id, exc_info=True)
if reaped:
logger.info("reaped %s stale script task(s)", reaped)
return reaped
def _reap_stale_standalone_image_tasks(*, team) -> None:
"""兜底:worker 崩溃/重启(OOM、部署)可能留下卡在 RESERVED 的出图任务,额度被一直占住、
前端轮询也永远等不到结果。超过 10 分钟(远大于单张真实出图耗时 ~60s)仍 RESERVED 的判为僵尸: