feat(ai-studio): separate image pool from task states

This commit is contained in:
chengma
2026-07-13 09:54:08 +08:00
parent 42fe233ed9
commit b1c050f633
9 changed files with 500 additions and 59 deletions
+46 -5
View File
@@ -194,7 +194,13 @@ def run_jobs(
if should_stop():
for future, job in list(futures.items()):
if future.cancel():
image_studio.update_job_status(job.id, "cancelled", error="用户停止", path=path)
image_studio.update_job_status(
job.id,
"cancelled",
error="用户停止",
recovery_action=_recovery_action_for_job(job),
path=path,
)
futures.pop(future, None)
record({"job": job, "status": "cancelled", "error": "用户停止"})
return summary
@@ -205,12 +211,24 @@ def _run_one_job(job_id, runtime, config, image_root, aspect_ratio, db_path, sho
if job is None:
raise ImageStudioGenerationError("AI工场生图任务不存在")
if should_stop():
updated = image_studio.update_job_status(job.id, "cancelled", error="用户停止", path=db_path)
updated = image_studio.update_job_status(
job.id,
"cancelled",
error="用户停止",
recovery_action=_recovery_action_for_job(job),
path=db_path,
)
return {"job": updated, "status": "cancelled", "error": "用户停止"}
project = image_studio.get_project(job.project_id, path=db_path)
source_asset = image_studio.get_asset(job.source_asset_id, path=db_path)
if project is None or source_asset is None:
updated = image_studio.update_job_status(job.id, "failed", error="项目或源图不存在", path=db_path)
updated = image_studio.update_job_status(
job.id,
"failed",
error="项目或源图不存在",
recovery_action=image_studio.JOB_RECOVERY_REGENERATE,
path=db_path,
)
return {"job": updated, "status": "failed", "error": "项目或源图不存在"}
try:
image_studio.update_job_status(job.id, "running", path=db_path)
@@ -248,7 +266,14 @@ def _run_one_job(job_id, runtime, config, image_root, aspect_ratio, db_path, sho
return {"job": updated, "asset": asset, "status": "succeeded"}
except Exception as exc:
status = "cancelled" if "停止" in str(exc) else "failed"
updated = image_studio.update_job_status(job.id, status, error=str(exc), path=db_path)
current_job = image_studio.get_job(job.id, path=db_path)
updated = image_studio.update_job_status(
job.id,
status,
error=str(exc),
recovery_action=_recovery_action_for_job(current_job),
path=db_path,
)
_notify(on_event, {"job_id": job.id, "step": "job_done", "result": status, "detail": str(exc)})
return {"job": updated, "status": status, "error": str(exc)}
@@ -363,7 +388,13 @@ def _poll_job(job_id, task_id, runtime, request_result, db_path, should_stop, on
if status in {"failed", "expired"}:
error = data.get("error") if isinstance(data.get("error"), dict) else {}
message = str(error.get("message") or error.get("code") or status)
image_studio.update_job_status(job_id, status, error=message, path=db_path)
image_studio.update_job_status(
job_id,
status,
error=message,
recovery_action=image_studio.JOB_RECOVERY_REGENERATE,
path=db_path,
)
raise ImageStudioGenerationError(message)
raise ImageStudioGenerationError("cmhub 生图任务状态返回格式错误")
@@ -394,3 +425,13 @@ def _raise_if_stopped(should_stop):
stopped = False
if stopped:
raise ImageStudioGenerationError("用户已停止,已提交任务可稍后继续查询")
def _recovery_action_for_job(job):
if (
job is not None
and getattr(job, "task_id", None)
and getattr(job, "recovery_action", None) == image_studio.JOB_RECOVERY_RESUME
):
return image_studio.JOB_RECOVERY_RESUME
return image_studio.JOB_RECOVERY_REGENERATE