How in BinanceSocketManager to handle the connection break correctly?

166 Views Asked by At

Good time of the day, tell me I can't beat the next disease in any way. I receive the found ohlcvs over the WS channel in real time. From time to time, my Internet connection disappears, sometimes when WS is connected for too long, Binance itself breaks the connection. I want to make sure that in case of disconnection, my program tries to connect again. To do this, I made a Try except block - if something bad happens in it, I just try to call the connect function again. It seems to sound logical and should work. However, during the test I get an error

Max reconnections 5 reached: CANCEL read_loop

At first, this error looks like I managed to catch it, but then the call stack follows and the program crashes

Traceback (most recent call last):
  File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/aiohttp/connector.py", line 1155, in _create_direct_connection
    hosts = await asyncio.shield(host_resolved)
  File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/aiohttp/connector.py", line 874, in _resolve_host
    addrs = await self._resolver.resolve(host, port, family=self._family)
  File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/aiohttp/resolver.py", line 33, in resolve
    infos = await self._loop.getaddrinfo(
  File "/usr/lib/python3.10/asyncio/base_events.py", line 863, in getaddrinfo
    return await self.run_in_executor(
  File "/usr/lib/python3.10/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/lib/python3.10/socket.py", line 955, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -3] Temporary failure in name resolution

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/master/PycharmProjects/PROJECT/main.py", line 43, in <module>
    loop.run_until_complete(main())
  File "/usr/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
    return future.result()
  File "/home/master/PycharmProjects/PROJECT/main.py", line 35, in main
    await asyncio.gather(stream.live_kline(), interrupt_sys.listen(), display(memory))
  File "/home/master/PycharmProjects/PROJECT/kernel/market/stream.py", line 45, in live_kline
    await self.connect()
  File "/home/master/PycharmProjects/PROJECT/kernel/market/stream.py", line 21, in connect
    self.__client = await AsyncClient.create(self.config.system_api_public_key,
  File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/binance/client.py", line 7866, in create
    await self.ping()
  File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/binance/client.py", line 7988, in ping
    return await self._get('ping', version=self.PRIVATE_API_VERSION)
  File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/binance/client.py", line 7953, in _get
    return await self._request_api('get', path, signed, version, **kwargs)
  File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/binance/client.py", line 7916, in _request_api
    return await self._request(method, uri, signed, **kwargs)
  File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/binance/client.py", line 7897, in _request
    async with getattr(self.session, method)(uri, **kwargs) as response:
  File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/aiohttp/client.py", line 1141, in __aenter__
    self._resp = await self._coro
  File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/aiohttp/client.py", line 536, in _request
    conn = await self._connector.connect(
  File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/aiohttp/connector.py", line 540, in connect
    proto = await self._create_connection(req, traces, timeout)
  File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/aiohttp/connector.py", line 901, in _create_connection
    _, proto = await self._create_direct_connection(req, traces, timeout)
  File "/home/master/PycharmProjects/PROJECT/venv/lib/python3.10/site-packages/aiohttp/connector.py", line 1169, in _create_direct_connection
    raise ClientConnectorError(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host api.binance.com:443 ssl:default [Temporary failure in name resolution]

Process finished with exit code 1

Tell me what's the matter - it feels like "try except" just doesn't work. Or is there something going on that I don't understand

How do I test? I just launch the application and then turn off the network card for more than 1 minute to simulate a connection break.

import asyncio
from binance import Client, AsyncClient, ThreadedWebsocketManager, ThreadedDepthCacheManager, BinanceSocketManager


class Stream:

    def __init__(self):
        self.__ts = None
        self.__chanel_name = None
        self.__bsm = None
        self.__client = None

    async def connect(self):
        self.__client = await AsyncClient.create('','')
        self.__bsm = BinanceSocketManager(self.__client, 60)
        self.__chanel_name = 'btcusdt@kline_1m'
        self.__ts = self.__bsm.futures_multiplex_socket([self.__chanel_name])

    async def live_kline(self):
        while True:
            try:
                async with self.__ts as tscm:
                    while True:
                        stream = await tscm.recv()
                        # Updates order statuses in real time
                        if stream['stream'] == self.__chanel_name:
                            Stream.process_message(stream)
            except Exception as e:
                print(f"An error occurred: {e}. Reconnecting...")
                await self.__client.close_connection()
                await asyncio.sleep(1)
                await self.connect()
                continue

    @staticmethod
    def process_message(msg: dict):

        pass

async def main():
    stream = Stream()
    await stream.connect()
    await asyncio.gather(stream.live_kline())
    loop.stop()
    
if __name__ == '__main__':
    loop = asyncio.new_event_loop()
    loop.run_until_complete(main())
0

There are 0 best solutions below