Skip to content

Commit 269fc07

Browse files
committed
fix: ensure read_loop properly closed when disposing transport
1 parent 2cce6fc commit 269fc07

1 file changed

Lines changed: 20 additions & 0 deletions

File tree

ably/transport/websockettransport.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,18 +229,38 @@ def on_read_loop_done(self, task: asyncio.Task):
229229

230230
async def dispose(self):
231231
self.is_disposed = True
232+
233+
# Cancel tasks but don't await them yet to avoid deadlock
234+
tasks_to_await = []
235+
232236
if self.read_loop:
233237
self.read_loop.cancel()
238+
tasks_to_await.append(self.read_loop)
234239
if self.ws_connect_task:
235240
self.ws_connect_task.cancel()
241+
tasks_to_await.append(self.ws_connect_task)
236242
if self.idle_timer:
237243
self.idle_timer.cancel()
244+
245+
# Schedule cleanup of cancelled tasks in the background to avoid blocking dispose()
246+
# This prevents deadlock when dispose() is called from within these tasks
247+
if tasks_to_await:
248+
asyncio.create_task(self._cleanup_tasks(tasks_to_await))
249+
238250
if self.websocket:
239251
try:
240252
await self.websocket.close()
241253
except asyncio.CancelledError:
242254
return
243255

256+
async def _cleanup_tasks(self, tasks):
257+
"""Wait for cancelled tasks to complete their cleanup."""
258+
for task in tasks:
259+
try:
260+
await task
261+
except Exception:
262+
pass # Ignore all exceptions from cancelled/failed tasks
263+
244264
async def close(self):
245265
await self.send({'action': ProtocolMessageAction.CLOSE})
246266

0 commit comments

Comments
 (0)