From 490ed273fc9f4a91f92ba7d2a5fa7387d1566f1b Mon Sep 17 00:00:00 2001 From: Chris Grady <17553614+CGFixIT@users.noreply.github.com> Date: Mon, 13 Jul 2026 14:25:21 -0400 Subject: [PATCH] perf(monitor): dedupe initial ws subscriptions --- polymarket_copier/core/monitor.py | 6 ++--- tests/test_monitor.py | 39 +++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/polymarket_copier/core/monitor.py b/polymarket_copier/core/monitor.py index f572f9f..37596f7 100644 --- a/polymarket_copier/core/monitor.py +++ b/polymarket_copier/core/monitor.py @@ -359,11 +359,11 @@ async def _ws_connect_and_listen(self) -> None: self._ws_healthy = True logger.info("WebSocket connected: %s", self._ws_url) + # The subscription snapshot is per socket, so reconnects must resync it. + self._last_subscribed = set() + await self._maybe_update_subscription(ws) heartbeat = asyncio.create_task(self._ws_heartbeat(ws)) try: - if self._subscribed_tokens: - await self._ws_send_subscription(ws, list(self._subscribed_tokens)) - async for raw_msg in ws: if self._stop_event.is_set(): break diff --git a/tests/test_monitor.py b/tests/test_monitor.py index 6f4f85c..35d28af 100644 --- a/tests/test_monitor.py +++ b/tests/test_monitor.py @@ -674,6 +674,45 @@ async def wake_sub_then_timeout_ping(): assert monitor._last_subscribed == {"tok-1"} assert wait_calls == 2 + @pytest.mark.asyncio + async def test_initial_ws_subscription_is_sent_once(self, monkeypatch): + """Initial sync must update the snapshot so the first message does not resend it.""" + sent = [] + monitor = TradeMonitor(tracked_wallets=["0xabc"], on_trade=_noop_trade) + monitor.subscribe_token("tok-1") + + class FakeWS: + def __init__(self): + self._messages = ["[]"] + + async def send(self, msg): + sent.append(json.loads(msg)) + + def __aiter__(self): + return self + + async def __anext__(self): + if self._messages: + return self._messages.pop() + raise StopAsyncIteration + + class FakeConnection: + async def __aenter__(self): + return ws + + async def __aexit__(self, *exc): + return False + + ws = FakeWS() + monkeypatch.setattr( + "polymarket_copier.core.monitor.websockets.connect", + lambda *args, **kwargs: FakeConnection(), + ) + + await monitor._ws_connect_and_listen() + + assert sent == [{"type": "market", "assets_ids": ["tok-1"]}] + # ─── C5: set_wallets — rebalance without KeyError on new wallets ──────────────