From 3657cfb6a2546daad1710a9ff9db5f9a3a5a5c26 Mon Sep 17 00:00:00 2001 From: Henry Su Date: Sat, 19 Sep 2026 23:09:26 -0500 Subject: [PATCH] fix(realtime): restart timeout after resending push --- src/realtime/src/realtime/_async/push.py | 1 + src/realtime/tests/test_push.py | 37 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/realtime/tests/test_push.py diff --git a/src/realtime/src/realtime/_async/push.py b/src/realtime/src/realtime/_async/push.py index a03b1b23..7c264fda 100644 --- a/src/realtime/src/realtime/_async/push.py +++ b/src/realtime/src/realtime/_async/push.py @@ -108,6 +108,7 @@ def start_timeout(self): async def timeout(self): await asyncio.sleep(self.timeout) + self.timeout_task = None self.trigger(RealtimeAcknowledgementStatus.Timeout, {}) if self.ref and self.ref in self.channel.messages_waiting_for_ack: del self.channel.messages_waiting_for_ack[self.ref] diff --git a/src/realtime/tests/test_push.py b/src/realtime/tests/test_push.py new file mode 100644 index 00000000..cd928a51 --- /dev/null +++ b/src/realtime/tests/test_push.py @@ -0,0 +1,37 @@ +from unittest.mock import AsyncMock, Mock + +import pytest + +from realtime._async.push import AsyncPush +from realtime.types import RealtimeAcknowledgementStatus + + +@pytest.mark.asyncio +async def test_resend_starts_a_new_timeout(): + channel = Mock() + channel.topic = "realtime:test" + channel.join_push.ref = "join-ref" + channel.messages_waiting_for_ack = {} + channel.socket._make_ref.side_effect = ["1", "2"] + channel.socket.send = AsyncMock() + + timeout_count = 0 + + def on_timeout(): + nonlocal timeout_count + timeout_count += 1 + + push = AsyncPush(channel, "broadcast", timeout=0) + push.receive(RealtimeAcknowledgementStatus.Timeout, on_timeout) + + await push.send() + first_timeout = push.timeout_task + assert first_timeout is not None + await first_timeout + + await push.resend() + second_timeout = push.timeout_task + assert second_timeout is not None + await second_timeout + + assert timeout_count == 2