mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-05-03 15:23:42 +03:00
Implement a mechanism to notify of connection failures (#852)
This commit is contained in:
parent
d9d586171f
commit
d5b349e031
|
@ -218,6 +218,14 @@ class TelegramBaseClient(abc.ABC):
|
||||||
def loop(self):
|
def loop(self):
|
||||||
return self._loop
|
return self._loop
|
||||||
|
|
||||||
|
@property
|
||||||
|
def disconnected(self):
|
||||||
|
"""
|
||||||
|
Future that resolves when the connection to Telegram
|
||||||
|
ends, either by user action or in the background.
|
||||||
|
"""
|
||||||
|
return self._sender.disconnected
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region Connecting
|
# region Connecting
|
||||||
|
|
|
@ -14,6 +14,19 @@ class UpdateMethods(UserMethods):
|
||||||
|
|
||||||
# region Public methods
|
# region Public methods
|
||||||
|
|
||||||
|
def run_until_disconnected(self):
|
||||||
|
"""
|
||||||
|
Runs the event loop until `disconnect` is called or if an error
|
||||||
|
while connecting/sending/receiving occurs in the background. In
|
||||||
|
the latter case, said error will ``raise`` so you have a chance
|
||||||
|
to ``except`` it on your own code.
|
||||||
|
|
||||||
|
This method shouldn't be called from ``async def`` as the loop
|
||||||
|
will be running already. Use ``await client.disconnected`` in
|
||||||
|
this situation instead.
|
||||||
|
"""
|
||||||
|
self.loop.run_until_complete(self.disconnected)
|
||||||
|
|
||||||
def on(self, event):
|
def on(self, event):
|
||||||
"""
|
"""
|
||||||
Decorator helper method around add_event_handler().
|
Decorator helper method around add_event_handler().
|
||||||
|
|
|
@ -63,6 +63,7 @@ class MTProtoSender:
|
||||||
# pending futures should be cancelled.
|
# pending futures should be cancelled.
|
||||||
self._user_connected = False
|
self._user_connected = False
|
||||||
self._reconnecting = False
|
self._reconnecting = False
|
||||||
|
self._disconnected = None
|
||||||
|
|
||||||
# We need to join the loops upon disconnection
|
# We need to join the loops upon disconnection
|
||||||
self._send_loop_handle = None
|
self._send_loop_handle = None
|
||||||
|
@ -157,6 +158,10 @@ class MTProtoSender:
|
||||||
self._recv_loop_handle.cancel()
|
self._recv_loop_handle.cancel()
|
||||||
|
|
||||||
__log__.info('Disconnection from {} complete!'.format(self._ip))
|
__log__.info('Disconnection from {} complete!'.format(self._ip))
|
||||||
|
if error:
|
||||||
|
self._disconnected.set_exception(error)
|
||||||
|
else:
|
||||||
|
self._disconnected.set_result(None)
|
||||||
|
|
||||||
def send(self, request, ordered=False):
|
def send(self, request, ordered=False):
|
||||||
"""
|
"""
|
||||||
|
@ -199,6 +204,17 @@ class MTProtoSender:
|
||||||
self._send_queue.put_nowait(message)
|
self._send_queue.put_nowait(message)
|
||||||
return message.future
|
return message.future
|
||||||
|
|
||||||
|
@property
|
||||||
|
def disconnected(self):
|
||||||
|
"""
|
||||||
|
Future that resolves when the connection to Telegram
|
||||||
|
ends, either by user action or in the background.
|
||||||
|
"""
|
||||||
|
if self._disconnected is not None:
|
||||||
|
return self._disconnected
|
||||||
|
else:
|
||||||
|
raise ConnectionError('Sender was never connected')
|
||||||
|
|
||||||
# Private methods
|
# Private methods
|
||||||
|
|
||||||
async def _connect(self):
|
async def _connect(self):
|
||||||
|
@ -235,9 +251,10 @@ class MTProtoSender:
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
await self._disconnect()
|
e = ConnectionError('auth_key generation failed {} times'
|
||||||
raise ConnectionError('auth_key generation failed {} times'
|
.format(self._retries))
|
||||||
.format(self._retries))
|
await self._disconnect(error=e)
|
||||||
|
raise e
|
||||||
|
|
||||||
__log__.debug('Starting send loop')
|
__log__.debug('Starting send loop')
|
||||||
self._send_loop_handle = self._loop.create_task(self._send_loop())
|
self._send_loop_handle = self._loop.create_task(self._send_loop())
|
||||||
|
@ -245,6 +262,9 @@ class MTProtoSender:
|
||||||
__log__.debug('Starting receive loop')
|
__log__.debug('Starting receive loop')
|
||||||
self._recv_loop_handle = self._loop.create_task(self._recv_loop())
|
self._recv_loop_handle = self._loop.create_task(self._recv_loop())
|
||||||
|
|
||||||
|
# First connection or manual reconnection after a failure
|
||||||
|
if self._disconnected is None or self._disconnected.done():
|
||||||
|
self._disconnected = asyncio.Future()
|
||||||
__log__.info('Connection to {} complete!'.format(self._ip))
|
__log__.info('Connection to {} complete!'.format(self._ip))
|
||||||
|
|
||||||
async def _reconnect(self):
|
async def _reconnect(self):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user