diff --git a/plugins/platforms/discord/adapter.py b/plugins/platforms/discord/adapter.py index c619880f81..3439d7c0a7 100644 --- a/plugins/platforms/discord/adapter.py +++ b/plugins/platforms/discord/adapter.py @@ -1287,9 +1287,10 @@ class DiscordAdapter(DiscordMediaMixin, BasePlatformAdapter): # ``socket_event_type`` for every parsed DISPATCH frame on every connection and it # is NOT gated behind ``enable_debug_events`` (unlike ``on_socket_raw_receive`` — # verified against discord.py 2.7.1 ``gateway.py``: ``received_message`` calls - # ``self._dispatch('socket_event_type', event)`` before the op-code switch). - # Heartbeat ACKs return before that dispatch, so an ACKing-but-deaf socket leaves - # this stamp frozen while every transport-side check reads healthy. + # ``self._dispatch('socket_event_type', event)`` before the op-code switch, gated + # on a non-null ``t``). Heartbeat ACK frames carry ``t: null`` and skip that + # dispatch, so an ACKing-but-deaf socket leaves this stamp frozen while every + # transport-side check reads healthy. adapter_self._last_dispatched_event_monotonic = time.perf_counter() @self._client.event diff --git a/tests/gateway/test_discord_event_silence.py b/tests/gateway/test_discord_event_silence.py index 351d65712a..33616ec533 100644 --- a/tests/gateway/test_discord_event_silence.py +++ b/tests/gateway/test_discord_event_silence.py @@ -111,9 +111,17 @@ async def test_zero_silence_bound_disables_only_that_dimension(monkeypatch): await _connect(adapter, monkeypatch, _dispatching_bot) bot = adapter._client - _transport_healthy(bot, ack_age=120.0) adapter._last_dispatched_event_monotonic = time.perf_counter() - 1000.0 + # Knob at 0: a stale stamp alone must read healthy (the dimension is off), + # with every transport-side sample green. + _transport_healthy(bot) + assert adapter._read_websocket_health(bot) == (True, "healthy") + + # Same stale stamp, now with a stale heartbeat ACK: the transport guards + # still trip, and only the ack-age dimension is named. + _transport_healthy(bot, ack_age=120.0) + await _wait_until(lambda: handler.await_count, "probe did not run with the knob at 0", timeout=8.0) assert adapter._fatal_error_code == "discord_websocket_health_stale" assert "ack_stale" in (adapter._fatal_error_message or "")