From b99e58bca14863c7f7a8b3054fb8e3e4b907a465 Mon Sep 17 00:00:00 2001 From: claude_dev Date: Thu, 13 Aug 2026 14:00:45 +0800 Subject: [PATCH] =?UTF-8?q?fix(api):=20GET=20/task=20=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=86=85=E5=AD=98=20running/pending=20=E4=BB=BB=E5=8A=A1(?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E4=B8=AD=E5=BF=83=E7=9C=8B=E5=88=B0=E5=88=9A?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E7=9A=84,=E6=B2=BB=E5=8F=AA=E6=9F=A5DB?= =?UTF-8?q?=E7=9C=8B=E4=B8=8D=E5=88=B0=E8=BF=90=E8=A1=8C=E4=B8=AD)=20[nas]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sanguo_api/routes.py | 48 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/sanguo_api/routes.py b/sanguo_api/routes.py index 9ff5767..134b8e5 100644 --- a/sanguo_api/routes.py +++ b/sanguo_api/routes.py @@ -324,14 +324,50 @@ def factor_report(task_id: str, factor: str, token: str = Query(...)): @router.get("/task", dependencies=[Depends(verify_token)]) def list_tasks(type: str | None = None, status: str | None = None): - """List historical tasks (from the results DB).""" + """List tasks: 内存中 running/pending + DB done/failed(历史)。 + + running/pending 任务还没存 DB(done 才 save_result),光查 DB 看不到刚提交的 + → 任务中心(GitHub Actions 模式)必须合并内存 active + DB 已完成。 + """ from sanguo_backtest.result_store import list_results orch = get_orchestrator() - items = [] + active: list[dict] = [] + seen: set[str] = set() + + # 1) 内存 active 任务 (running/pending,未存 DB) + for tid, task in list(getattr(orch.pool, "_tasks", {}).items()): + st = task.status.value if hasattr(task.status, "value") else str(task.status) + if st not in ("running", "pending"): + continue + if status and st != status: + continue + ttype = getattr(task, "task_type", "") or "" + if type and ttype != type: + continue + spec = getattr(orch, "_pending", {}).get(tid, {}) or {} + strat = spec.get("strategy", "") + if not strat and spec.get("strategy_class"): + strat = getattr(spec["strategy_class"], "__name__", str(spec["strategy_class"])) + active.append({ + "id": 0, + "task_id": tid, + "type": ttype, + "status": st, + "strategy": strat, + "symbol": spec.get("symbol", "") or spec.get("benchmark", ""), + "start": spec.get("start", ""), + "end": spec.get("end", ""), + }) + seen.add(tid) + + # 2) DB 已持久化任务 (done/failed) + db_items: list[dict] = [] for r in list_results(type_filter=type, db_path=orch.db_path): + if r.task_id in seen: + continue if status and r.status != status: continue - items.append({ + db_items.append({ "id": r.id, "task_id": r.task_id, "type": r.type, @@ -341,8 +377,10 @@ def list_tasks(type: str | None = None, status: str | None = None): "start": r.start, "end": r.end, }) - items.reverse() # newest first - return {"tasks": items} + + active.reverse() # 最新提交的 running 在最上 + db_items.reverse() # DB newest first + return {"tasks": active + db_items} @router.get("/task/{task_id}/optimization-results", dependencies=[Depends(verify_token)])