fix(api): GET /task 内存失后 DB fallback 返 status(治回测 done 后前端轮询 404 死循环卡等待) [nas]
This commit is contained in:
+19
-2
@@ -131,10 +131,27 @@ async def submit_factor(req: FactorAnalysisRequest):
|
|||||||
@router.get("/task/{task_id}", dependencies=[Depends(verify_token)])
|
@router.get("/task/{task_id}", dependencies=[Depends(verify_token)])
|
||||||
def get_status(task_id: str):
|
def get_status(task_id: str):
|
||||||
"""Get task status"""
|
"""Get task status"""
|
||||||
s = get_orchestrator().get_status(task_id)
|
orch = get_orchestrator()
|
||||||
|
s = orch.get_status(task_id)
|
||||||
if s is None:
|
if s is None:
|
||||||
|
# 内存池无此 task(容器重启/已完成被清)→查 DB;有持久化结果则返其 status,
|
||||||
|
# 否则真不存在。治:done task 内存清后 GET /task 404 → 前端轮询死循环卡等待,
|
||||||
|
# 但结果其实在 DB(历史能查)。CTA/组合回测 done 后内存失均受益。
|
||||||
|
try:
|
||||||
|
from sanguo_backtest.result_store import load_result_by_task_id
|
||||||
|
if orch.db_path:
|
||||||
|
r = load_result_by_task_id(task_id, orch.db_path)
|
||||||
|
if r is not None:
|
||||||
|
return {
|
||||||
|
"task_id": task_id,
|
||||||
|
"status": r.status or "done",
|
||||||
|
"stage": "",
|
||||||
|
"error_msg": None,
|
||||||
|
}
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
raise HTTPException(status_code=404, detail="task not found")
|
raise HTTPException(status_code=404, detail="task not found")
|
||||||
pool = get_orchestrator().pool
|
pool = orch.pool
|
||||||
stage = pool.get_stage(task_id)
|
stage = pool.get_stage(task_id)
|
||||||
task = pool.get_task(task_id)
|
task = pool.get_task(task_id)
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
"""GET /task/{id} 内存失后 DB fallback (治 done task 内存清后前端轮询 404 死循环卡等待)。"""
|
||||||
|
from fastapi.testclient import TestClient
|
||||||
|
|
||||||
|
from sanguo_api.app import create_app
|
||||||
|
from sanguo_api.auth import set_jwt_config, create_token
|
||||||
|
from sanguo_backtest.result_store import BacktestResult, save_result
|
||||||
|
|
||||||
|
|
||||||
|
def _auth_client(tmp_path):
|
||||||
|
set_jwt_config("test_secret_dbfb", 60)
|
||||||
|
db = str(tmp_path / "r.db")
|
||||||
|
app = create_app(db_path=db)
|
||||||
|
c = TestClient(app)
|
||||||
|
token = create_token("admin")
|
||||||
|
return c, {"Authorization": f"Bearer {token}"}, db
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_status_returns_done_when_only_in_db(tmp_path):
|
||||||
|
"""内存池无(容器重启/清理)但 DB 有 done 结果 → 返回 done,不 404。"""
|
||||||
|
c, h, db = _auth_client(tmp_path)
|
||||||
|
save_result(
|
||||||
|
BacktestResult(
|
||||||
|
task_id="cta_dbfb", type="cta", status="done", strategy="DoubleMa",
|
||||||
|
symbol="600519.SH", params={}, start="2024-01-02", end="2024-03-29",
|
||||||
|
statistics={}, equity_curve=None, trades=None,
|
||||||
|
),
|
||||||
|
db_path=db,
|
||||||
|
)
|
||||||
|
r = c.get("/api/v1/task/cta_dbfb", headers=h)
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert r.json()["status"] == "done"
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_status_404_when_neither_memory_nor_db(tmp_path):
|
||||||
|
c, h, _db = _auth_client(tmp_path)
|
||||||
|
r = c.get("/api/v1/task/nonexistent_xyz", headers=h)
|
||||||
|
assert r.status_code == 404
|
||||||
Reference in New Issue
Block a user