Skip to content

Commit 58c1730

Browse files
committed
fix(session): ensure safe closure of connection and cancellation of receive task
1 parent a522e65 commit 58c1730

File tree

3 files changed

+585
-471
lines changed

3 files changed

+585
-471
lines changed

.pre-commit-config.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ repos:
2020
- id: check-yaml
2121

2222
- repo: https://github.com/astral-sh/ruff-pre-commit
23-
rev: v0.11.7
23+
rev: v0.12.5
2424
hooks:
25+
- id: ruff-check
26+
args: [--fix, --ignore=E501, --unsafe-fixes, --exit-non-zero-on-fix]
2527
- id: ruff-format
26-
- id: ruff
27-
args: [--fix, --ignore=E501, --exit-non-zero-on-fix]

hydrogram/session/session.py

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ def __init__(
111111
self.recv_task = None
112112

113113
self.is_started = asyncio.Event()
114+
self.restart_lock = asyncio.Lock()
114115

115116
self.last_reconnect_attempt = None
116117

@@ -182,12 +183,16 @@ async def stop(self):
182183

183184
self.ping_task_event.clear()
184185

185-
await self.connection.close()
186+
if self.connection:
187+
await self.connection.close()
186188

187-
if self.recv_task:
189+
if self.recv_task and not self.recv_task.done():
188190
self.recv_task.cancel()
189-
with contextlib.suppress(asyncio.CancelledError):
190-
await self.recv_task
191+
192+
with contextlib.suppress(asyncio.CancelledError, asyncio.TimeoutError, RuntimeError):
193+
await asyncio.wait_for(self.recv_task, timeout=1.0)
194+
195+
self.recv_task = None
191196

192197
if not self.is_media and callable(self.client.disconnect_handler):
193198
try:
@@ -198,17 +203,18 @@ async def stop(self):
198203
log.info("Session stopped")
199204

200205
async def restart(self):
201-
now = datetime.now()
202-
if (
203-
self.last_reconnect_attempt
204-
and now - self.last_reconnect_attempt < self.RECONNECT_THRESHOLD
205-
):
206-
log.info("Reconnecting too frequently, sleeping for a while")
207-
await asyncio.sleep(5)
208-
209-
self.last_reconnect_attempt = now
210-
await self.stop()
211-
await self.start()
206+
async with self.restart_lock:
207+
now = datetime.now()
208+
if (
209+
self.last_reconnect_attempt
210+
and now - self.last_reconnect_attempt < self.RECONNECT_THRESHOLD
211+
):
212+
log.info("Reconnecting too frequently, sleeping for a while")
213+
await asyncio.sleep(5)
214+
215+
self.last_reconnect_attempt = now
216+
await self.stop()
217+
await self.start()
212218

213219
async def handle_packet(self, packet):
214220
data = await self.client.loop.run_in_executor(

0 commit comments

Comments
 (0)