fix: Añadir reintentos de conexión MySQL y limitar reinicios de servicios
- get_connection() reintenta hasta 30 veces con delays de 2s - iniciar_todo.py limita reinicios a 3 por servicio con cooldown de 60s - Evitar loops infinitos cuando MySQL no está disponible
This commit is contained in:
@@ -1,10 +1,13 @@
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
import mysql.connector
|
import mysql.connector
|
||||||
import json
|
import json
|
||||||
|
import time
|
||||||
from mysql.connector import Error as MySQLError
|
from mysql.connector import Error as MySQLError
|
||||||
from botdiscord.config import get_db_config, get_db_type
|
from botdiscord.config import get_db_config, get_db_type
|
||||||
|
|
||||||
_connection = None
|
_connection = None
|
||||||
|
MAX_CONNECTION_RETRIES = 30
|
||||||
|
CONNECTION_RETRY_DELAY = 2
|
||||||
|
|
||||||
def get_connection():
|
def get_connection():
|
||||||
global _connection
|
global _connection
|
||||||
@@ -13,39 +16,53 @@ def get_connection():
|
|||||||
if db_type == "mysql":
|
if db_type == "mysql":
|
||||||
db_config = get_db_config()
|
db_config = get_db_config()
|
||||||
|
|
||||||
# Si no hay conexión o no está activa, intentamos conectar/reconectar
|
|
||||||
if _connection is None:
|
if _connection is None:
|
||||||
try:
|
for attempt in range(1, MAX_CONNECTION_RETRIES + 1):
|
||||||
_connection = mysql.connector.connect(
|
try:
|
||||||
host=db_config.get("host"),
|
_connection = mysql.connector.connect(
|
||||||
port=db_config.get("port"),
|
host=db_config.get("host"),
|
||||||
user=db_config.get("user"),
|
port=db_config.get("port"),
|
||||||
password=db_config.get("password"),
|
user=db_config.get("user"),
|
||||||
database=db_config.get("name"),
|
password=db_config.get("password"),
|
||||||
consume_results=True,
|
database=db_config.get("name"),
|
||||||
connection_timeout=5
|
consume_results=True,
|
||||||
)
|
connection_timeout=10
|
||||||
except MySQLError as e:
|
)
|
||||||
print(f"CRITICAL: Could not establish initial MySQL connection: {e}")
|
print(f"[DB] MySQL conectado exitosamente")
|
||||||
raise
|
break
|
||||||
|
except MySQLError as e:
|
||||||
|
if attempt < MAX_CONNECTION_RETRIES:
|
||||||
|
print(f"[DB] Intento {attempt}/{MAX_CONNECTION_RETRIES}: MySQL no disponible, reintentando en {CONNECTION_RETRY_DELAY}s...")
|
||||||
|
time.sleep(CONNECTION_RETRY_DELAY)
|
||||||
|
_connection = None
|
||||||
|
else:
|
||||||
|
print(f"[DB] CRITICAL: No se pudo conectar a MySQL después de {MAX_CONNECTION_RETRIES} intentos")
|
||||||
|
raise
|
||||||
|
|
||||||
# Verificar salud de la conexión existente
|
|
||||||
try:
|
try:
|
||||||
_connection.ping(reconnect=True, attempts=3, delay=1)
|
_connection.ping(reconnect=True, attempts=3, delay=1)
|
||||||
except MySQLError:
|
except MySQLError:
|
||||||
try:
|
for attempt in range(1, 6):
|
||||||
_connection = mysql.connector.connect(
|
try:
|
||||||
host=db_config.get("host"),
|
print(f"[DB] Reconectando a MySQL (intento {attempt}/5)...")
|
||||||
port=db_config.get("port"),
|
_connection = mysql.connector.connect(
|
||||||
user=db_config.get("user"),
|
host=db_config.get("host"),
|
||||||
password=db_config.get("password"),
|
port=db_config.get("port"),
|
||||||
database=db_config.get("name"),
|
user=db_config.get("user"),
|
||||||
consume_results=True,
|
password=db_config.get("password"),
|
||||||
connection_timeout=5
|
database=db_config.get("name"),
|
||||||
)
|
consume_results=True,
|
||||||
except MySQLError as e:
|
connection_timeout=10
|
||||||
print(f"CRITICAL: MySQL reconnection failed: {e}")
|
)
|
||||||
raise
|
print(f"[DB] MySQL reconectado exitosamente")
|
||||||
|
break
|
||||||
|
except MySQLError as e:
|
||||||
|
if attempt < 5:
|
||||||
|
time.sleep(2)
|
||||||
|
_connection = None
|
||||||
|
else:
|
||||||
|
print(f"[DB] CRITICAL: MySQL reconnection failed: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
return _connection
|
return _connection
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ print("🤖 Iniciando Bots de Traducción...")
|
|||||||
print("=" * 40)
|
print("=" * 40)
|
||||||
|
|
||||||
processes = []
|
processes = []
|
||||||
|
restart_counts = {}
|
||||||
|
MAX_RESTARTS = 3
|
||||||
|
RESTART_COOLDOWN = 60
|
||||||
|
|
||||||
def start_process(cmd, name, delay_before=0):
|
def start_process(cmd, name, delay_before=0):
|
||||||
if delay_before > 0:
|
if delay_before > 0:
|
||||||
@@ -72,11 +75,32 @@ signal.signal(signal.SIGTERM, signal_handler)
|
|||||||
while True:
|
while True:
|
||||||
for p, name in processes:
|
for p, name in processes:
|
||||||
if p.poll() is not None:
|
if p.poll() is not None:
|
||||||
log(f"⚠️ {name} se detuvo, reiniciando...")
|
if name not in restart_counts:
|
||||||
|
restart_counts[name] = {"count": 0, "last_restart": 0}
|
||||||
|
|
||||||
|
current_time = time.time()
|
||||||
|
|
||||||
|
if current_time - restart_counts[name]["last_restart"] > RESTART_COOLDOWN:
|
||||||
|
restart_counts[name]["count"] = 0
|
||||||
|
|
||||||
|
restart_counts[name]["count"] += 1
|
||||||
|
restart_counts[name]["last_restart"] = current_time
|
||||||
|
|
||||||
|
if restart_counts[name]["count"] > MAX_RESTARTS:
|
||||||
|
log(f"⛔ {name} se detuvo {restart_counts[name]['count']} veces. Demasiados reinicios. Esperando {RESTART_COOLDOWN}s...")
|
||||||
|
time.sleep(RESTART_COOLDOWN)
|
||||||
|
restart_counts[name]["count"] = 0
|
||||||
|
continue
|
||||||
|
|
||||||
|
log(f"⚠️ {name} se detuvo (intento {restart_counts[name]['count']}/{MAX_RESTARTS}), reiniciando...")
|
||||||
|
|
||||||
|
delay = 5 if name != "Discord Bot" else 10
|
||||||
|
|
||||||
if name == "Discord Bot":
|
if name == "Discord Bot":
|
||||||
p1 = start_process(["python3", "-X", "faulthandler", "-X", "importsys", "botdiscord/bot.py"], "Discord Bot", delay_before=10)
|
p1 = start_process(["python3", "-X", "faulthandler", "-X", "importsys", "botdiscord/bot.py"], "Discord Bot", delay_before=delay)
|
||||||
elif name == "Telegram Bot":
|
elif name == "Telegram Bot":
|
||||||
p2 = start_process(["python3", "-X", "faulthandler", "-X", "importsys", "bottelegram/telegram_bot.py"], "Telegram Bot", delay_before=5)
|
p2 = start_process(["python3", "-X", "faulthandler", "-X", "importsys", "bottelegram/telegram_bot.py"], "Telegram Bot", delay_before=delay)
|
||||||
elif name == "Panel Web":
|
elif name == "Panel Web":
|
||||||
p3 = start_process(["python3", "-X", "faulthandler", "-X", "importsys", "panel/main.py"], "Panel Web", delay_before=0)
|
p3 = start_process(["python3", "-X", "faulthandler", "-X", "importsys", "panel/main.py"], "Panel Web", delay_before=0)
|
||||||
|
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
|
|||||||
Reference in New Issue
Block a user