retry query class

This commit is contained in:
2021-07-30 16:50:33 +03:00
parent eb4dd88558
commit ba6fba6b5f
4 changed files with 45 additions and 434 deletions

34
orm/_retry.py Normal file
View File

@@ -0,0 +1,34 @@
from sqlalchemy.exc import OperationalError, StatementError
from sqlalchemy.orm.query import Query as _Query
from time import sleep
class RetryingQuery(_Query):
__max_retry_count__ = 3
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def __iter__(self):
attempts = 0
while True:
attempts += 1
try:
return super().__iter__()
except OperationalError as ex:
if "server closed the connection unexpectedly" not in str(ex):
raise
if attempts <= self.__max_retry_count__:
sleep_for = 2 ** (attempts - 1)
logging.error(
"/!\ Database connection error: retrying Strategy => sleeping for {}s"
" and will retry (attempt #{} of {}) \n Detailed query impacted: {}".format(
sleep_for, attempts, self.__max_retry_count__, ex)
)
sleep(sleep_for)
continue
else:
raise
except StatementError as ex:
if "reconnect until invalid transaction is rolled back" not in str(ex):
raise
self.session.rollback()

View File

@@ -6,8 +6,17 @@ from sqlalchemy.orm import sessionmaker
from sqlalchemy.sql.schema import Table
from settings import DB_URL
from _retry import RetryingQuery
engine = create_engine(DB_URL, convert_unicode=True, echo=False)
# engine = create_engine(DB_URL, convert_unicode=True, echo=False)
engine = sqlalchemy.create_engine(connection_string,
pool_size=10,
max_overflow=2,
pool_recycle=300,
pool_pre_ping=True,
pool_use_lifo=True)
sqlalchemy.orm.sessionmaker(bind=engine, query_cls=RetryingQuery)
Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
global_session = Session()