mirror of
https://github.com/Mayuri-Chan/pyrofork.git
synced 2026-01-05 23:04:51 +00:00
refactor(session): replace recursion with loop and add backoff
This refactor replaces recursion with a loop in the session invoke logic. Additionally, a backoff mechanism has been introduced to prevent frequent restarts from crashing the bot. Signed-off-by: wulan17 <wulan17@komodos.id>
This commit is contained in:
parent
b79ffac690
commit
01e7717e52
1 changed files with 18 additions and 4 deletions
|
|
@ -21,6 +21,7 @@ import asyncio
|
||||||
import bisect
|
import bisect
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
from datetime import datetime, timedelta
|
||||||
from hashlib import sha1
|
from hashlib import sha1
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
@ -56,6 +57,7 @@ class Session:
|
||||||
ACKS_THRESHOLD = 10
|
ACKS_THRESHOLD = 10
|
||||||
PING_INTERVAL = 5
|
PING_INTERVAL = 5
|
||||||
STORED_MSG_IDS_MAX_SIZE = 500
|
STORED_MSG_IDS_MAX_SIZE = 500
|
||||||
|
RECONNECT_THRESHOLD = timedelta(seconds=10)
|
||||||
|
|
||||||
TRANSPORT_ERRORS = {
|
TRANSPORT_ERRORS = {
|
||||||
404: "auth key not found",
|
404: "auth key not found",
|
||||||
|
|
@ -103,6 +105,8 @@ class Session:
|
||||||
|
|
||||||
self.loop = asyncio.get_event_loop()
|
self.loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
|
self.last_reconnect_attempt = None
|
||||||
|
|
||||||
async def start(self):
|
async def start(self):
|
||||||
while True:
|
while True:
|
||||||
self.connection = self.client.connection_factory(
|
self.connection = self.client.connection_factory(
|
||||||
|
|
@ -186,6 +190,15 @@ class Session:
|
||||||
log.info("Session stopped")
|
log.info("Session stopped")
|
||||||
|
|
||||||
async def restart(self):
|
async def restart(self):
|
||||||
|
now = datetime.now()
|
||||||
|
if (
|
||||||
|
self.last_reconnect_attempt
|
||||||
|
and now - self.last_reconnect_attempt < self.RECONNECT_THRESHOLD
|
||||||
|
):
|
||||||
|
log.info("Reconnecting too frequently, sleeping for a while")
|
||||||
|
await asyncio.sleep(5)
|
||||||
|
|
||||||
|
self.last_reconnect_attempt = now
|
||||||
await self.stop()
|
await self.stop()
|
||||||
await self.start()
|
await self.start()
|
||||||
|
|
||||||
|
|
@ -415,7 +428,7 @@ class Session:
|
||||||
|
|
||||||
query_name = ".".join(inner_query.QUALNAME.split(".")[1:])
|
query_name = ".".join(inner_query.QUALNAME.split(".")[1:])
|
||||||
|
|
||||||
while True:
|
while retries > 0:
|
||||||
try:
|
try:
|
||||||
return await self.send(query, timeout=timeout)
|
return await self.send(query, timeout=timeout)
|
||||||
except (FloodWait, FloodPremiumWait) as e:
|
except (FloodWait, FloodPremiumWait) as e:
|
||||||
|
|
@ -429,15 +442,16 @@ class Session:
|
||||||
|
|
||||||
await asyncio.sleep(amount)
|
await asyncio.sleep(amount)
|
||||||
except (OSError, InternalServerError, ServiceUnavailable) as e:
|
except (OSError, InternalServerError, ServiceUnavailable) as e:
|
||||||
|
retries -= 1
|
||||||
if retries == 0:
|
if retries == 0:
|
||||||
raise e from None
|
raise e
|
||||||
|
|
||||||
(log.warning if retries < 2 else log.info)(
|
(log.warning if retries < 2 else log.info)(
|
||||||
'[%s] Retrying "%s" due to: %s',
|
'[%s] Retrying "%s" due to: %s',
|
||||||
Session.MAX_RETRIES - retries + 1,
|
Session.MAX_RETRIES - retries,
|
||||||
query_name, str(e) or repr(e)
|
query_name, str(e) or repr(e)
|
||||||
)
|
)
|
||||||
|
|
||||||
await asyncio.sleep(0.5)
|
await asyncio.sleep(0.5)
|
||||||
|
|
||||||
return await self.invoke(query, retries - 1, timeout)
|
raise TimeoutError("Exceeded maximum number of retries")
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue