Итак, я разрабатываю эту онлайн-игру, похожую на telnet, и она не очень популярна (кто знает, когда-нибудь), поэтому соединение с базой данных моего игрового движка не используется часами по ночам. Это один сценарий, который ожидает событий, поэтому он продолжает работать.
При первом выполнении запроса после нескольких часов бездействия я получаю mariadb.DatabaseError при попытке выполнить курсор. Если я повторю запрос, он снова работает. Таким образом, хотя функция выдает исключение о потере соединения, она восстанавливает его.
Мой вопрос: как мне справиться с этим?
Это вещи, которые я вижу в качестве возможных решений, но, на мой взгляд, они не очень хороши:
- обертывание каждого запроса в структуру try-except, делает код громоздким, в основном ненужным и повторяющимся кодом
- написание моей собственной функции «декоратора» для выполнения запроса, который затем повторно инициализирует базу данных, когда я получаю mariadb.DatabaseError, что кажется лучше, но заставляет меня писать функции-оболочки вокруг (почти) идеально работающих библиотечных функций
- выполнение в основном бессмысленного запроса «ping» каждые N минут, что создает нагрузку на базу данных, которая бесполезна в 99,9% случаев.
Вот код для иллюстрации:
import mariadb
class Db:
...
def __init__(self):
self.conn = mariadb.connect(user=self.__db_user, password=self.__db_pass, host=self.__db_host, port=self.__db_port, database=self.__db_name)
def one_of_many_functions(self, ...):
cur = self.conn.cursor()
cur.execute('SELECT ...') # Here is where the mariadb.DatabaseError happens after long inactivity, and otherwise runs fine
...
На самом деле я действительно не понимаю, почему реализация mariadb в python не справляется с этим. Когда соединение потеряно, cur.execute выдаст mariadb.DatabaseError, но никаких действий предпринимать не нужно, потому что, если я повторю запрос с тем же соединением с базой данных, оно снова сработает. Таким образом, соединение восстанавливается само. Почему компонент заставляет меня запрашивать, в то время как он «восстанавливает» само соединение и может снова запросить?
Но поскольку это то, что есть, мой вопрос: как лучше всего справиться с этим?