modified: app.py
modified: bot.py
This commit is contained in:
80
app.py
80
app.py
@@ -7,6 +7,7 @@ from requests_oauthlib import OAuth2Session
|
||||
import os
|
||||
import subprocess
|
||||
import psutil
|
||||
import time
|
||||
import mysql.connector
|
||||
import mysql.connector.pooling
|
||||
from datetime import datetime, timedelta
|
||||
@@ -89,7 +90,7 @@ def stop_bot():
|
||||
# Database Connection Pool für bessere Verbindungsverwaltung
|
||||
app_pool = mysql.connector.pooling.MySQLConnectionPool(
|
||||
pool_name="app_pool",
|
||||
pool_size=15, # Reduziert von 20 auf 15 (Bot: 30, App: 15 = max 45 statt 50+)
|
||||
pool_size=8, # Stark reduziert von 15 auf 8 (Bot: 25, App: 8 = 33 total)
|
||||
pool_reset_session=True,
|
||||
host=DB_HOST,
|
||||
port=DB_PORT,
|
||||
@@ -109,14 +110,24 @@ def get_db_connection():
|
||||
return connection
|
||||
except mysql.connector.PoolError as e:
|
||||
print(f"Pool error in app.py: {e}")
|
||||
# Fallback zu direkter Verbindung bei Pool-Problemen
|
||||
# Besserer Fallback mit Retry-Mechanismus
|
||||
for attempt in range(3):
|
||||
try:
|
||||
print(f"Attempting direct connection (attempt {attempt + 1}/3)")
|
||||
return mysql.connector.connect(
|
||||
host=DB_HOST,
|
||||
port=DB_PORT,
|
||||
user=DB_USER,
|
||||
password=DB_PASS,
|
||||
database=DB_NAME
|
||||
database=DB_NAME,
|
||||
connect_timeout=5,
|
||||
autocommit=True
|
||||
)
|
||||
except Exception as retry_error:
|
||||
print(f"Direct connection attempt {attempt + 1} failed: {retry_error}")
|
||||
if attempt == 2: # Letzter Versuch
|
||||
raise retry_error
|
||||
time.sleep(1) # Kurze Pause zwischen Versuchen
|
||||
|
||||
from contextlib import contextmanager
|
||||
|
||||
@@ -231,6 +242,24 @@ def landing_page():
|
||||
"""Landing Page"""
|
||||
return render_template("landing.html")
|
||||
|
||||
@app.route("/db_status")
|
||||
def db_status():
|
||||
"""Debug-Route für DB-Pool Status"""
|
||||
try:
|
||||
status = get_pool_status()
|
||||
with get_db_cursor() as (cursor, connection):
|
||||
cursor.execute("SELECT 1")
|
||||
db_ok = True
|
||||
except Exception as e:
|
||||
status = {"error": str(e)}
|
||||
db_ok = False
|
||||
|
||||
return jsonify({
|
||||
"pool_status": status,
|
||||
"database_ok": db_ok,
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
|
||||
@app.route("/about")
|
||||
def about():
|
||||
"""Öffentliche Über-uns-Seite"""
|
||||
@@ -268,29 +297,56 @@ def load_user_data():
|
||||
g.is_admin = session.get("is_admin", False)
|
||||
g.bot_running = bot_status() # Lädt den Bot-Status in g
|
||||
|
||||
# Hole die Liste der Gilden aus der Datenbank
|
||||
connection = get_db_connection()
|
||||
cursor = connection.cursor(dictionary=True)
|
||||
|
||||
# Lade die Gilden des Nutzers
|
||||
# Lade die Gilden des Nutzers aus der Session (ohne DB-Zugriff)
|
||||
user_guilds = session.get("discord_guilds", [])
|
||||
|
||||
# Nur DB-Zugriff wenn Gilden-Daten nicht im Cache sind
|
||||
guild_cache_key = f"guild_cache_{g.user_info['id']}"
|
||||
if guild_cache_key not in session or not session[guild_cache_key]:
|
||||
try:
|
||||
with get_db_cursor() as (cursor, connection):
|
||||
user_guild_ids = [guild["id"] for guild in user_guilds]
|
||||
|
||||
if user_guild_ids: # Nur wenn Gilden existieren
|
||||
# Finde nur die Gilden, die auch in der Datenbank existieren
|
||||
cursor.execute("SELECT guild_id FROM guilds WHERE guild_id IN (%s)" % ','.join(['%s'] * len(user_guild_ids)), user_guild_ids)
|
||||
placeholders = ','.join(['%s'] * len(user_guild_ids))
|
||||
cursor.execute(f"SELECT guild_id FROM guilds WHERE guild_id IN ({placeholders})", user_guild_ids)
|
||||
existing_guilds = cursor.fetchall()
|
||||
existing_guild_ids = {g["guild_id"] for g in existing_guilds}
|
||||
|
||||
# Filtere die Gilden des Nutzers basierend auf der Existenz in der Datenbank
|
||||
g.guilds = [guild for guild in user_guilds if int(guild["id"]) in {g["guild_id"] for g in existing_guilds}]
|
||||
filtered_guilds = [guild for guild in user_guilds if int(guild["id"]) in existing_guild_ids]
|
||||
|
||||
cursor.close()
|
||||
connection.close()
|
||||
# Cache die gefilterten Gilden für 5 Minuten
|
||||
session[guild_cache_key] = filtered_guilds
|
||||
session[f"{guild_cache_key}_time"] = time.time()
|
||||
g.guilds = filtered_guilds
|
||||
else:
|
||||
g.guilds = []
|
||||
except Exception as e:
|
||||
print(f"Error loading guild data: {e}")
|
||||
# Fallback: Verwende alle Gilden aus der Session
|
||||
g.guilds = user_guilds
|
||||
# Setze einen Flag für DB-Probleme
|
||||
g.db_error = True
|
||||
else:
|
||||
# Prüfe Cache-Alter (5 Minuten TTL)
|
||||
cache_time = session.get(f"{guild_cache_key}_time", 0)
|
||||
if time.time() - cache_time > 300: # 5 Minuten
|
||||
# Cache ist abgelaufen, lösche ihn
|
||||
session.pop(guild_cache_key, None)
|
||||
session.pop(f"{guild_cache_key}_time", None)
|
||||
g.guilds = user_guilds # Fallback
|
||||
else:
|
||||
# Verwende gecachte Daten
|
||||
g.guilds = session[guild_cache_key]
|
||||
else:
|
||||
# Falls der Benutzer nicht eingeloggt ist, keine Daten setzen
|
||||
g.user_info = None
|
||||
g.is_admin = False
|
||||
g.guilds = []
|
||||
g.bot_running = False
|
||||
g.db_error = False
|
||||
|
||||
@app.route("/callback")
|
||||
def callback():
|
||||
|
||||
2
bot.py
2
bot.py
@@ -196,7 +196,7 @@ def retry_query(func, *args, retries=3, delay=5):
|
||||
|
||||
pool = mysql.connector.pooling.MySQLConnectionPool(
|
||||
pool_name="mypool",
|
||||
pool_size=25, # Reduziert von 30 auf 25 (App: 15, Bot: 25 = 40 total)
|
||||
pool_size=15, # Weiter reduziert von 25 auf 15 (App: 8, Bot: 15 = 23 total)
|
||||
pool_reset_session=True,
|
||||
autocommit=True,
|
||||
host=DB_HOST,
|
||||
|
||||
Reference in New Issue
Block a user