feat(agent-office): node_monitor에 trade-monitor 워커 등재 + trader 링크 from을 워커명으로 수정
WSL 워커 관측 규칙 — 모든 WSL docker 워커는 /infra에서 모니터링 가능해야 함.
trade-monitor(kind=trader) 등재 → /nodes·/infra 노출. 링크 from 하드코딩('ai_trade')을
w[name]으로 고쳐 다중 trader가 각자 링크를 갖도록 함. 미배포 워커는 prev=None이라 다운 경보 없음.
This commit is contained in:
@@ -16,6 +16,7 @@ WORKER_REGISTRY = [
|
|||||||
{"name": "insta-render", "kind": "render", "queue": "queue:insta-render"},
|
{"name": "insta-render", "kind": "render", "queue": "queue:insta-render"},
|
||||||
{"name": "task-watcher", "kind": "watcher", "queue": None},
|
{"name": "task-watcher", "kind": "watcher", "queue": None},
|
||||||
{"name": "ai_trade", "kind": "trader", "queue": None},
|
{"name": "ai_trade", "kind": "trader", "queue": None},
|
||||||
|
{"name": "trade-monitor", "kind": "trader", "queue": None},
|
||||||
]
|
]
|
||||||
|
|
||||||
_redis = None
|
_redis = None
|
||||||
@@ -92,7 +93,7 @@ async def collect_status(redis=None) -> dict:
|
|||||||
|
|
||||||
for w in out["workers"]:
|
for w in out["workers"]:
|
||||||
if w["kind"] == "trader":
|
if w["kind"] == "trader":
|
||||||
out["links"].append({"from": "ai_trade", "to": "nas-stock", "type": "http-pull",
|
out["links"].append({"from": w["name"], "to": "nas-stock", "type": "http-pull",
|
||||||
"status": "healthy" if w["alive"] else "down"})
|
"status": "healthy" if w["alive"] else "down"})
|
||||||
elif w["kind"] == "render":
|
elif w["kind"] == "render":
|
||||||
out["links"].append({"from": "nas", "to": w["name"], "type": "redis-queue",
|
out["links"].append({"from": "nas", "to": w["name"], "type": "redis-queue",
|
||||||
|
|||||||
@@ -68,6 +68,18 @@ async def test_trader_http_pull_link():
|
|||||||
link = next(l for l in st["links"] if l["from"] == "ai_trade")
|
link = next(l for l in st["links"] if l["from"] == "ai_trade")
|
||||||
assert link["type"] == "http-pull" and link["status"] == "healthy"
|
assert link["type"] == "http-pull" and link["status"] == "healthy"
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_trade_monitor_registered_and_own_link():
|
||||||
|
"""WSL 워커 trade-monitor가 registry에 있어 /nodes에 노출되고, 링크 from은
|
||||||
|
ai_trade 하드코딩이 아니라 자기 이름(trade-monitor)이어야 한다 (다중 trader 구분)."""
|
||||||
|
r = FakeRedis(kv={"worker:trade-monitor:heartbeat": _hb("trade-monitor", "trader", "market_open")})
|
||||||
|
st = await node_monitor.collect_status(redis=r)
|
||||||
|
tm = next(w for w in st["workers"] if w["name"] == "trade-monitor")
|
||||||
|
assert tm["alive"] is True and tm["kind"] == "trader"
|
||||||
|
link = next(l for l in st["links"] if l["from"] == "trade-monitor")
|
||||||
|
assert link["type"] == "http-pull" and link["to"] == "nas-stock" and link["status"] == "healthy"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_paused_no_watcher_heartbeat_fallback_reason():
|
async def test_paused_no_watcher_heartbeat_fallback_reason():
|
||||||
"""paused=True인데 watcher heartbeat 없으면 paused_reason == 'trading' 폴백."""
|
"""paused=True인데 watcher heartbeat 없으면 paused_reason == 'trading' 폴백."""
|
||||||
|
|||||||
Reference in New Issue
Block a user