From 6d23f7b5ec89a7a04ef09021aec1283fe91846aa Mon Sep 17 00:00:00 2001 From: claude_dev Date: Sun, 2 Aug 2026 07:14:00 +0800 Subject: [PATCH] =?UTF-8?q?fix(portfolio):=20worker=20=5FTIMEOUT=203600?= =?UTF-8?q?=E2=86=9210800(3h)+timeout=E9=9D=9E=E9=9D=99=E9=BB=98=E6=97=A5?= =?UTF-8?q?=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 全市场(max_pool=0)全周期(726天)回测每策略 60-100min,原 3600s(1h)不够→ subprocess.run kill→_wait_future 静默 task.fail→404。改 10800(3h)覆盖。 加 try/except TimeoutExpired 显式 logger.error(task_id+argv)+raise RuntimeError, timeout 不再静默(治基建反馈排查困难) --- sanguo_orchestrator/portfolio_worker.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/sanguo_orchestrator/portfolio_worker.py b/sanguo_orchestrator/portfolio_worker.py index c6b46b2..0427136 100644 --- a/sanguo_orchestrator/portfolio_worker.py +++ b/sanguo_orchestrator/portfolio_worker.py @@ -21,7 +21,7 @@ logger = logging.getLogger(__name__) _VPS_HOST = "49.232.102.198" _VPS_WORKDIR = r"C:\\sanguo_vnpy_v2" _VPS_PYTHON = "python" -_TIMEOUT = 3600 # 1 hour hard cap (was 600s sync in routes_portfolio) +_TIMEOUT = 10800 # 3h hard cap (was 3600/1h; 全市场全周期 60-100min/策略不够) def run_portfolio_task(spec: dict) -> Any: @@ -56,10 +56,21 @@ def run_portfolio_task(spec: dict) -> Any: argv, cwd = _build_argv(start, end, cash, benchmark, max_pool, provider_config, strategy) logger.info("[portfolio_worker] task=%s running: %s", task_id, " ".join(argv[3:])) - proc = subprocess.run( - argv, cwd=cwd, capture_output=True, text=True, - timeout=_TIMEOUT, check=False, - ) + try: + proc = subprocess.run( + argv, cwd=cwd, capture_output=True, text=True, + timeout=_TIMEOUT, check=False, + ) + except subprocess.TimeoutExpired: + # 全市场全周期慢→3h仍超→显式log(否则_wait_future静默task.fail难排查) + logger.error( + "[portfolio_worker] task=%s TIMEOUT after %ss (argv tail=%s)", + task_id, _TIMEOUT, " ".join(argv[3:]), + ) + raise RuntimeError( + f"runner_backtest timeout after {_TIMEOUT}s " + f"(全市场全周期?考虑缩小 universe 或周期)" + ) if proc.returncode != 0: stderr_tail = (proc.stderr or "")[-2000:]