fix(shadow): 多账户worker不抢全局solo锁——根因实锤:__main__对--account N也走~/.sanguo_shadow_desk.lock全局锁,全机只放行一个影子worker(谁先抢到谁活),supervisor多账户并存时其余全部'锁占用'rc=0优雅退出→每60s重拉秒退循环;VPS实录40/41反复退出+42抢到锁独活(shadow_41.log一击定位);单账户时代从未暴露,2026-08-16用户建三影子账户即炸。修:--account分支跳过全局锁直进run_shadow(同账户防重复由bullet_trade runtime/shadow_{aid}实例锁+supervisor children表兜底);solo模式(无--account)维持全局锁防双开;+3路由测试(account跳锁/solo持锁/auto不碰柜台);936绿 [vps]
This commit is contained in:
@@ -60,6 +60,15 @@ def main() -> int:
|
||||
|
||||
run_auto_supervisor()
|
||||
return 0
|
||||
if "--account" in sys.argv:
|
||||
# 多账户 worker 不抢全局 solo 锁:全局锁全机只放行一个 worker,supervisor
|
||||
# 多账户并存时其余全部"锁占用"优雅退出(VPS 2026-08-16 实录 40/41 反复
|
||||
# rc=0,单账户时代从未暴露)。同账户防重复由 bullet_trade
|
||||
# runtime/shadow_{aid} 实例锁兜底,supervisor children 表保证一账户一进程。
|
||||
from .runner import run_shadow
|
||||
|
||||
run_shadow()
|
||||
return 0
|
||||
lock = _acquire_lock()
|
||||
if lock is None:
|
||||
print("影子柜台已在运行(锁占用),本次启动退出。", flush=True)
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
"""影子柜台 CLI 路由:--account worker 不抢全局 solo 锁(多账户并存的前提)。"""
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def _run_main(monkeypatch, argv):
|
||||
from sanguo_trader.shadow import __main__ as m
|
||||
|
||||
calls = {"lock": 0, "shadow": 0, "auto": 0}
|
||||
|
||||
def _no_lock():
|
||||
calls["lock"] += 1
|
||||
return object()
|
||||
|
||||
def _shadow(*a, **k):
|
||||
calls["shadow"] += 1
|
||||
|
||||
def _auto(*a, **k):
|
||||
calls["auto"] += 1
|
||||
|
||||
import sanguo_trader.shadow.runner as runner_mod
|
||||
import sanguo_trader.shadow.supervisor as sup
|
||||
|
||||
monkeypatch.setattr(m, "_acquire_lock", _no_lock)
|
||||
# main() 内 lazy import:patch 源模块而非 __main__
|
||||
monkeypatch.setattr(runner_mod, "run_shadow", _shadow)
|
||||
monkeypatch.setattr(sup, "run_auto_supervisor", _auto)
|
||||
monkeypatch.setattr(sys, "argv", ["prog", *argv])
|
||||
rc = m.main()
|
||||
return rc, calls
|
||||
|
||||
|
||||
def test_account_worker_skips_global_lock(monkeypatch):
|
||||
"""--account N:多账户 worker 不碰全局锁(VPS 实录 40/41「锁占用」循环退出)。"""
|
||||
rc, calls = _run_main(monkeypatch, ["--account", "41"])
|
||||
assert rc == 0
|
||||
assert calls["shadow"] == 1
|
||||
assert calls["lock"] == 0 # 关键:不抢全局 solo 锁
|
||||
|
||||
|
||||
def test_solo_mode_still_locks(monkeypatch):
|
||||
"""无 --account 的 solo 模式维持全局锁(防双开)。"""
|
||||
rc, calls = _run_main(monkeypatch, [])
|
||||
assert rc == 0
|
||||
assert calls["shadow"] == 1
|
||||
assert calls["lock"] == 1
|
||||
|
||||
|
||||
def test_auto_mode_no_lock_no_shadow(monkeypatch):
|
||||
"""--auto 主管:既不抢锁也不起柜台。"""
|
||||
rc, calls = _run_main(monkeypatch, ["--auto"])
|
||||
assert rc == 0
|
||||
assert calls["auto"] == 1
|
||||
assert calls["lock"] == 0
|
||||
assert calls["shadow"] == 0
|
||||
Reference in New Issue
Block a user