-
-
Notifications
You must be signed in to change notification settings - Fork 161
Description
I'm developing a system where a socketio.AsyncClient client needs to be "always" connected to it's server (an socketio.AsyncServer).
Of course, the connection will crash once in a while, because there is a network (and an Nginx proxy) between them, and these things have interruptions or crashes once in a while.
I'm actualy noticing that interruptions are not at all rare, and it's also a possibility that my client will sometimes get starved of resources and not be able to "ping" the server for 25 seconds (as described #83 ), from looking at the logs it appears that it is happening at least once a day.
So I would like to have my client recover from connection failures by detecting them and reconnecting, and I was wondering what was the best way to do this, (i.e. which exceptions should be caught etc). The client looks more or less like this :
async def trigger_event(self, event, *args):
"...process the incoming event"
def start(self):
async def start_client():
await self.socketio_client.connect(self.url)
while True:
for m in self.ui_janitor.messages_for_round():
await self.client.emit('broadcast', m)
await asyncio.sleep("...x seconds, based on some throttling logic")
loop = asyncio.get_event_loop()
loop.run_until_complete(start_client())
As can be seen in this pseudo code, the client is both reacting to events that gets sent to it, and emiting messages from an infinite janitor / deamon loop.
I'm thinking that something like the pseudo code below could do, but this kind of approach will only work if I catch the right exceptions, and I should also not be catching the ones that are not recoverable, or not raised as a result of connection failures, and I should probably intruduce some backoff, sleep and retry logic.
Any advice on how to properly implement a "quasi permenant" / "recovering" connection would be appreciated.
def start(self):
async def start_client():
await self.socketio_client.connect(self.url)
while True:
for m in self.ui_janitor.messages_for_round():
await self.client.emit('broadcast', m)
await asyncio.sleep("...x seconds, based on some throttling logic")
while True:
try:
loop = asyncio.get_event_loop()
loop.run_until_complete(start_client())
except engineio.exceptions.ConnectionError ex:
logger.info(f"will reconnect...")