单图生成改为异步(Celery+AITask+前端轮询),与视频同架构

把独立生图从「请求内同步出图」改成异步任务,彻底根治整站 502:
- 后端 enqueue_standalone_images:Web 请求只建任务+预留额度(秒级),慢 ARK 出图派发给
  Celery worker(generate_standalone_image_task)。Web 层不再被 ~30s 请求占住 worker,
  健康探针不会被饿死 → 整站 502 从根上消失。
- run_standalone_image_task:worker 内单张出图,成功落库扣费/失败退费,幂等(只处理 RESERVED,
  重复投递不二次扣费)。
- 提交成功后浏览器关闭/断网,worker 仍把图生成并落库,重开素材库即可见(异步天然抗断连)。
- 视图 POST 返回 202+任务列表,新增 GET ?ids= 轮询状态并带回成图;前端 submit+poll。
- count 上限 4→12,与 UI 一致。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
zyc
2026-06-15 16:38:06 +08:00
co-authored by Claude Opus 4.8
parent 3472c3cc9c
commit a749be5837
5 changed files with 131 additions and 65 deletions
+10
View File
@@ -10,3 +10,13 @@ def submit_ai_task(self, task_id: str) -> str:
def poll_ai_task(self, task_id: str) -> str:
return task_id
@app.task(bind=True, max_retries=0)
def generate_standalone_image_task(self, task_id: str) -> str:
"""单张独立图的慢活(ARK 出图 ~30s)在 worker 内跑,Web 层不被占住。
幂等且失败自退费(见 run_standalone_image_task),故 max_retries=0,不向上抛重试。"""
from apps.ai.services import run_standalone_image_task
run_standalone_image_task(task_id=task_id)
return task_id