Nuestra aplicación funcionaba bien hasta que la migramos a la base de datos de Microsoft para PostgreSQL en Azure. Luego, periódicamente, nuestra aplicación falla sin motivo real y tenemos errores SSL SYSCALL por todas partes, en DELETE, etc. Hemos intentado todo lo descrito en Internet: use argumentos de keepalive, RAM, memoria y todo lo demás. Queremos intentar restablecer automáticamente la conexión. Pero tenemos un grupo de conexiones roscadas. he mirado este hilo Psycopg2 reconexión automática dentro de una clase Pero nuestras funciones que leen la base de datos están en otra clase. Así que tenemos dos preguntas:
1) ¿Cuál es la causa de los errores SSL SYSCALL? He buscado en todos los hilos y los sospechosos habituales están descartados. 2) ¿Cómo me vuelvo a conectar en caso de falla dentro de una clase de grupo de conexiones roscadas --> esto se está usando en una aplicación de matraz?
Así es como está estructurada nuestra aplicación
class DBClass(object): _instance = None conn= None def __new__(cls): if cls._instance is None: cls._instance = object.__new__(cls) try: max_conn = 12 keepalive_args = { "keepalives": 1, "keepalives_idle": 25, "keepalives_interval": 4,"keepalives_count": 9, } db._instance.pool = psycopg2.pool.ThreadedConnectionPool(3, max_conn, db=, host=, user=, password=, port=, **keepalive_args) except Exception as ex: db._instance = None raise ex return cls._instance def __enter__(self): self.conn= self._instance.pool.getconn() return self def __exit__(self, exc_type, exc_val, exc_tb): self._instance.pool.putconn(self.connection) def __del__(self): self._instance.pool.closeall()#otro módulo de python tiene una clase llamada clsEmployee. Tenemos docenas de funciones que utilizan la clase de base de datos mencionada anteriormente. Algo como esto.
with DBClass() as db: pg_conn = db.connection cur = pg_conn.cursor() cur.execute("SELECT * from emp") row = cur.fetchone()[0]Hay muchas maneras de manejar esto.
La solución propuesta por la reconexión automática de Psycopg2 dentro de una clase seguirá funcionando si sus llamadas para ejecutar el trabajo de db están fuera de DBClass. Solo necesita funciones que llamen a la base de datos y las envuelve con un decorador. Todo lo que está haciendo el decorador es agregar un bucle para permitir que la función se llame varias veces, envolviendo la función real en un intento/excepto y reconectando en un excepto. En realidad, esta es una forma bastante estándar de manejar este tipo de problema, ya que puede funcionar para DB, API o cualquier cosa que pueda fallar. Lo único que puede querer hacer es agregar un retroceso exponencial a su reintento (donde está la llamada de suspensión).
La otra opción que tiene es crear su propia subclase de cursor que tenga la misma lógica de reintento dentro de una versión anulada de ejecutar. Esto logrará lo mismo, es solo un caso de lo que cree que es más fácil trabajar.
Dado que esto se usa en una aplicación de Flask, puede modificar el primer enfoque y, en lugar de hacer el reintento en el nivel de código del modelo, puede hacer el reintento en el nivel de ruta de Flask.