From e24dd3ad751b32eddbea7b8ea6e15083f385a18e Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Wed, 7 Aug 2019 23:43:31 +0200 Subject: [PATCH] Prevent double-connect causing double-reads later Which leads to "RuntimeError: readexactly() called while another coroutine is already waiting for incoming data" being raised, and causing everything to break or halt. --- telethon/client/telegrambaseclient.py | 7 +++++-- telethon/network/mtprotosender.py | 15 +++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/telethon/client/telegrambaseclient.py b/telethon/client/telegrambaseclient.py index 1d09f3ad..6d09344d 100644 --- a/telethon/client/telegrambaseclient.py +++ b/telethon/client/telegrambaseclient.py @@ -405,14 +405,17 @@ class TelegramBaseClient(abc.ABC): except OSError: print('Failed to connect') """ - await self._sender.connect(self._connection( + if not await self._sender.connect(self._connection( self.session.server_address, self.session.port, self.session.dc_id, loop=self._loop, loggers=self._log, proxy=self._proxy - )) + )): + # We don't want to init or modify anything if we were already connected + return + self.session.auth_key = self._sender.auth_key self.session.save() diff --git a/telethon/network/mtprotosender.py b/telethon/network/mtprotosender.py index 0da0ad69..c83240c0 100644 --- a/telethon/network/mtprotosender.py +++ b/telethon/network/mtprotosender.py @@ -54,6 +54,7 @@ class MTProtoSender: self._auth_key_callback = auth_key_callback self._update_callback = update_callback self._auto_reconnect_callback = auto_reconnect_callback + self._connect_lock = asyncio.Lock(loop=loop) # Whether the user has explicitly connected or disconnected. # @@ -114,13 +115,15 @@ class MTProtoSender: """ Connects to the specified given connection using the given auth key. """ - if self._user_connected: - self._log.info('User is already connected!') - return + async with self._connect_lock: + if self._user_connected: + self._log.info('User is already connected!') + return False - self._connection = connection - await self._connect() - self._user_connected = True + self._connection = connection + await self._connect() + self._user_connected = True + return True def is_connected(self): return self._user_connected