fix: 修正模型超时与结果未知重放

This commit is contained in:
hh
2026-07-21 15:34:29 +08:00
parent a99aae8231
commit f2114bc36e
22 changed files with 1221 additions and 107 deletions
+2 -31
View File
@@ -306,8 +306,8 @@ def _unavailable_library_asset_target(resolved_assets: list[dict], raw_message:
def _reap_stale_free_video_tasks(*, team) -> None:
"""僵尸回收(趁每次新提交顺手做,无需定时任务):
· RESERVED 超 10 分钟:没提交到火山就死(worker 崩溃/进程重启)→ 标失败退费;
· SUBMITTED/POLLING 超 2 小时:轮询链早已断且无人认领(正常出片 5-10 分钟)→ 标失败退费;
· RESERVED 超过视频提交阶段总时限:没提交到火山就死(worker 崩溃/进程重启)→ 标失败退费;
· SUBMITTED/POLLING 已有远端任务 ID,只能按供应商终态收尾,不按本地等待时间回收;
· POSTPROCESSING 超 30 分钟:转存/结算中途崩溃 → 标失败退费(火山可能已出片,平台承担该笔成本)。"""
now = timezone.now()
from .routing_policy import load_model_routing_policy
@@ -319,11 +319,6 @@ def _reap_stale_free_video_tasks(*, team) -> None:
{"updated_at__lt": now - timedelta(seconds=video_policy.submit_total_timeout)},
"任务未在配置的提交总时限内完成(自动回收)",
),
(
[AITask.Status.SUBMITTED, AITask.Status.POLLING],
{"submitted_at__lt": now - timedelta(seconds=video_policy.generation_timeout)},
"生成超过配置的成片等待总时限(自动回收)",
),
(
[AITask.Status.POSTPROCESSING],
{"updated_at__lt": now - timedelta(minutes=30)},
@@ -669,30 +664,6 @@ def finalize_free_video(*, task: AITask) -> AITask:
from .services import get_video_provider
video_policy = load_model_routing_policy().video
if task.submitted_at and (
timezone.now() - task.submitted_at
).total_seconds() >= video_policy.generation_timeout:
timeout_message = "视频生成超过配置的成片等待总时限"
public_error = classify_generation_error(
TimeoutError(timeout_message),
operation="video_generate",
reference_id=str(task.id),
)
with transaction.atomic():
locked = AITask.objects.select_for_update().get(id=task.id)
if locked.status not in (AITask.Status.SUBMITTED, AITask.Status.POLLING):
return locked
locked.status = AITask.Status.FAILED
locked.error_code = "GenerationTimeout"
locked.error_message = timeout_message
locked.completed_at = timezone.now()
locked.save(
update_fields=["status", "error_code", "error_message", "completed_at", "updated_at"]
)
release_credit(reservation=locked.credit_reservation, reason=timeout_message)
_notify_failure(locked, raw=timeout_message, hint=public_error.fallback_message)
return locked
submit_attempt = (
task.model_attempts.filter(status="succeeded", operation="video_generate")
.select_related("model_config__provider")