fix(runtime): recover awake ownership and batch model failures
This commit is contained in:
1 parent
6b2c0f199d
commit
baf069854b
17 files changed
+477
-32
No files matched your search
@@ -15,6 +15,7 @@ from artemis.runtime.task_limits import task_timeout
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
TERMINAL = {"completed", "failed", "cancelled", "skipped", "interrupted"}
|
||||
MODEL_PAUSE_REASON = "模型请求已暂停,请先恢复模型连接再继续批次"
|
||||
background_tasks: set[asyncio.Task] = set()
|
||||
|
||||
|
||||
@@ -123,7 +124,9 @@ def recover_batches():
|
||||
if any(str(job["session_id"]) in live_sessions for job in store.jobs(batch["id"])):
|
||||
continue
|
||||
batch.update(
|
||||
status="paused", reason="服务已重启;请检查中断任务,点击继续执行未开始任务"
|
||||
status="paused",
|
||||
reason="服务已重启;请检查中断任务,点击继续执行未开始任务",
|
||||
pause_source="recovery",
|
||||
)
|
||||
for job in store.jobs(batch["id"]):
|
||||
if job["status"] in {"running", "queued", "finalizing", "task_paused", "resuming"}:
|
||||
@@ -164,9 +167,29 @@ async def on_terminal(item: dict, status: str):
|
||||
}
|
||||
):
|
||||
job["status"] = "failed"
|
||||
job["error"] = job.get("error") or "任务执行结束,但业务检查未通过"
|
||||
job["error"] = (
|
||||
job.get("error")
|
||||
or report.get("error")
|
||||
or (report.get("test_result") or {}).get("reason")
|
||||
or "任务未完成或验证未通过,请查看报告中的具体原因"
|
||||
)
|
||||
elif job["status"] == "failed" and report.get("error") and not job.get("error"):
|
||||
job["error"] = report["error"]
|
||||
if job["status"] == "failed" and report["outcome"].get("code") == "initialization_failed":
|
||||
job["failure_code"] = "initialization_failed"
|
||||
batch = store.get("batch", job.get("batch_id")) if job.get("batch_id") else None
|
||||
if (
|
||||
batch
|
||||
and (batch["status"] == "running" or batch.get("pause_source") == "model")
|
||||
and any(j["status"] == "pending" for j in store.jobs(batch["id"]))
|
||||
):
|
||||
batch.update(
|
||||
status="paused",
|
||||
pause_source="initialization",
|
||||
reason="任务初始化失败;请处理环境问题后继续剩余用例:"
|
||||
+ (job.get("error") or "请查看任务报告"),
|
||||
)
|
||||
store.put("batch", batch["id"], batch)
|
||||
# Persist terminal classification before export, but the coordinator waits for finalization.
|
||||
store.save_job({**job, "status": "finalizing", "terminal_status": job["status"]})
|
||||
await asyncio.to_thread(export_session, sid, job["formats"])
|
||||
@@ -217,10 +240,18 @@ async def tick_batches():
|
||||
if batch["status"] not in {"running", "paused"}:
|
||||
continue
|
||||
jobs = store.jobs(batch["id"])
|
||||
if (
|
||||
batch["status"] == "paused"
|
||||
and batch.get("pause_source") == "model"
|
||||
and not state.is_paused
|
||||
):
|
||||
batch.update(status="running", reason="")
|
||||
batch.pop("pause_source", None)
|
||||
store.put("batch", batch["id"], batch)
|
||||
active = [j for j in jobs if j["status"] in {"running", "queued", "finalizing"}]
|
||||
if active:
|
||||
if state.is_paused:
|
||||
batch.update(status="paused", reason="模型请求已暂停,请先恢复模型连接再继续批次")
|
||||
if state.is_paused and batch["status"] == "running":
|
||||
batch.update(status="paused", reason=MODEL_PAUSE_REASON, pause_source="model")
|
||||
store.put("batch", batch["id"], batch)
|
||||
for job in active:
|
||||
# The queue records started_at at submission, then replaces it
|
||||
@@ -284,7 +315,7 @@ async def tick_batches():
|
||||
store.put("batch", batch["id"], batch)
|
||||
continue
|
||||
if state.is_paused:
|
||||
batch.update(status="paused", reason="模型请求已暂停,请先恢复模型连接再继续批次")
|
||||
batch.update(status="paused", reason=MODEL_PAUSE_REASON, pause_source="model")
|
||||
store.put("batch", batch["id"], batch)
|
||||
continue
|
||||
job = pending[0]
|
||||
@@ -438,11 +469,14 @@ def batch_action(batch_id: str, action: str) -> dict:
|
||||
if action == "pause":
|
||||
if batch["status"] not in {"running", "paused"}:
|
||||
raise ValueError("只能暂停正在执行的批次")
|
||||
batch.update(status="paused", reason="用户暂停;当前任务继续,后续任务等待")
|
||||
batch.update(
|
||||
status="paused", reason="用户暂停;当前任务继续,后续任务等待", pause_source="user"
|
||||
)
|
||||
elif action == "resume":
|
||||
if batch["status"] not in {"draft", "paused"}:
|
||||
raise ValueError("只能开始草稿或继续已暂停批次")
|
||||
batch.update(status="running", reason="")
|
||||
batch.pop("pause_source", None)
|
||||
elif action == "retry_failed":
|
||||
if batch["status"] == "running":
|
||||
raise ValueError("请先暂停批次")
|
||||
|
||||
Reference in new issue
Block a user