47 lines
1.8 KiB
Python
47 lines
1.8 KiB
Python
"""VPS 引擎数清点(vps_restart_resident.sh 核验用,2026-08-30 live_17/20 教训)。
|
|
|
|
用法(promote 已部署到 VPS C:\\sanguo_vnpy_v2\\scripts\\ci\\ 后,经 ssh 调):
|
|
python vps_count_engines.py expected # 杀树前:DB running 数(期望值)
|
|
python vps_count_engines.py actual # 重拉后:实际引擎进程数
|
|
|
|
输出一行 ``LIVE=<n> SHADOW=<m>``。两种模式必须分开调——expected 必须在杀树
|
|
之前取,重拉后 DB 的 status 已被死亡事件改写,再查就不是期望了。
|
|
|
|
自匹配陷阱:本进程(wmic 的父 python)命令行只含本脚本路径,不含
|
|
``sanguo_portfolio.runner_live`` / ``sanguo_trader.shadow --account`` 字样,
|
|
wmic.exe 又被 name='python.exe' 过滤——计数不会把自己算进去(08-30 手工
|
|
wmic 探测时 -c 脚本文本含关键字曾 +1 误计)。
|
|
"""
|
|
import sqlite3
|
|
import subprocess
|
|
import sys
|
|
|
|
DB = r"C:\sanguo_vnpy_v2\data\backtest_results.db"
|
|
|
|
|
|
def _expected() -> tuple[int, int]:
|
|
c = sqlite3.connect(DB)
|
|
live = c.execute(
|
|
"select count(*) from live_accounts where status='running'").fetchone()[0]
|
|
shadow = c.execute(
|
|
"select count(*) from paper_accounts where status='running'").fetchone()[0]
|
|
c.close()
|
|
return live, shadow
|
|
|
|
|
|
def _actual() -> tuple[int, int]:
|
|
out = subprocess.run(
|
|
["wmic", "process", "where", "name='python.exe'",
|
|
"get", "CommandLine", "/format:csv"],
|
|
capture_output=True, text=True, errors="replace").stdout
|
|
lines = out.splitlines()
|
|
live = sum("sanguo_portfolio.runner_live" in l for l in lines)
|
|
shadow = sum("sanguo_trader.shadow --account" in l for l in lines)
|
|
return live, shadow
|
|
|
|
|
|
if __name__ == "__main__":
|
|
mode = sys.argv[1] if len(sys.argv) > 1 else ""
|
|
live, shadow = _expected() if mode == "expected" else _actual()
|
|
print(f"LIVE={live} SHADOW={shadow}")
|