From 9053eed999c85df9ff91bc392fa763b7f259723e Mon Sep 17 00:00:00 2001 From: DeltaX <33706469+DeltaXWizard@users.noreply.github.com> Date: Wed, 14 Sep 2022 18:05:48 -0400 Subject: [PATCH 1/3] feat: Utilise reconnection lock for packet sending. --- interactions/api/gateway/client.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/interactions/api/gateway/client.py b/interactions/api/gateway/client.py index 7b2b3cb7a..f8d73e49f 100644 --- a/interactions/api/gateway/client.py +++ b/interactions/api/gateway/client.py @@ -959,16 +959,18 @@ async def _send_packet(self, data: Dict[str, Any]) -> None: """ _data = dumps(data) if isinstance(data, dict) else data packet: str = _data.decode("utf-8") if isinstance(_data, bytes) else _data + log.debug(packet) - if data["op"] != OpCodeType.HEARTBEAT.value: - # This is because the ratelimiter limits already accounts for this. - await self._ratelimiter.block() + async with self.reconnect_lock: # needs to lock while it reconnects. - if self._client is not None: # this mitigates against another edge case. - self._last_send = perf_counter() - log.debug(packet) + if data["op"] != OpCodeType.HEARTBEAT.value: + # This is because the ratelimiter limits already accounts for this. + await self._ratelimiter.block() - await self._client.send_str(packet) + if self._client is not None: # this mitigates against another edge case. + self._last_send = perf_counter() + + await self._client.send_str(packet) async def __identify( self, shard: Optional[List[Tuple[int]]] = None, presence: Optional[ClientPresence] = None From 7f60b16fa998985e3d39fc1d8fe50be683c66277 Mon Sep 17 00:00:00 2001 From: DeltaX <33706469+DeltaXWizard@users.noreply.github.com> Date: Thu, 15 Sep 2022 17:22:22 -0400 Subject: [PATCH 2/3] chore: bump version --- interactions/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interactions/base.py b/interactions/base.py index ba2efa784..9dd345ba2 100644 --- a/interactions/base.py +++ b/interactions/base.py @@ -6,7 +6,7 @@ "__authors__", ) -__version__ = "4.3.2-beta.1" +__version__ = "4.3.2-rc.1" __authors__ = { "current": [ From 8633077fb1c5819920c2c075d1721ad72868098f Mon Sep 17 00:00:00 2001 From: DeltaX <33706469+DeltaXWizard@users.noreply.github.com> Date: Sat, 17 Sep 2022 15:34:49 -0400 Subject: [PATCH 3/3] fix: Fix race condition when reconnecting and identifying/resuming using the shared reconnect lock. --- interactions/api/gateway/client.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/interactions/api/gateway/client.py b/interactions/api/gateway/client.py index f8d73e49f..b2ccc9827 100644 --- a/interactions/api/gateway/client.py +++ b/interactions/api/gateway/client.py @@ -961,16 +961,25 @@ async def _send_packet(self, data: Dict[str, Any]) -> None: packet: str = _data.decode("utf-8") if isinstance(_data, bytes) else _data log.debug(packet) - async with self.reconnect_lock: # needs to lock while it reconnects. + if data["op"] in {OpCodeType.IDENTIFY.value, OpCodeType.RESUME.value}: + # This can't use the reconnect lock *because* its already referenced in + # self._reconnect(), hence an infinite hang. - if data["op"] != OpCodeType.HEARTBEAT.value: - # This is because the ratelimiter limits already accounts for this. - await self._ratelimiter.block() - - if self._client is not None: # this mitigates against another edge case. + if self._client is not None: self._last_send = perf_counter() await self._client.send_str(packet) + else: + async with self.reconnect_lock: # needs to lock while it reconnects. + + if data["op"] != OpCodeType.HEARTBEAT.value: + # This is because the ratelimiter limits already accounts for this. + await self._ratelimiter.block() + + if self._client is not None: # this mitigates against another edge case. + self._last_send = perf_counter() + + await self._client.send_str(packet) async def __identify( self, shard: Optional[List[Tuple[int]]] = None, presence: Optional[ClientPresence] = None