From 9afc29a8bb7b6a862412494e5fb84941ba6daab3 Mon Sep 17 00:00:00 2001 From: patrick Date: Thu, 3 Sep 2026 01:58:33 +0200 Subject: [PATCH] =?UTF-8?q?fix(redis):=20Timeouts=20f=C3=BCr=20Async-Pool?= =?UTF-8?q?=20+=20Start-Health-Check-Log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit get_async_redis() hatte keine socket_connect_timeout/socket_timeout/ max_connections – ein gehängtes Redis hätte Requests unbegrenzt blockiert statt schnell zu failen. Zusätzlich einmaliger Ping im Lifespan-Startup, nur zur Log-Sichtbarkeit (blockiert Boot nicht). Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_015Ahyx6D3r7G1EuAc42nezn --- backend/app/core/redis.py | 14 +++++++++++++- backend/app/main.py | 11 +++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/backend/app/core/redis.py b/backend/app/core/redis.py index 4beb7e3..30737da 100644 --- a/backend/app/core/redis.py +++ b/backend/app/core/redis.py @@ -36,13 +36,25 @@ def get_async_redis(): kiosk_security._check_and_set_nonce) – der Pool verwaltet Connections selbst. Verbindungsfehler zeigen sich erst beim ersten Call (kein Ping hier), Aufrufer müssen weiterhin except behandeln (Nonce-Fallback, TOTP-Lockout). + + Timeouts analog zum sync-Client gesetzt, sonst würde ein gehängtes Redis + (statt eines klaren Connection-Refused) Requests unbegrenzt blockieren. + max_connections deckt Lastspitzen bei einem uvicorn-Worker ab, ohne dass + ein einzelner langsamer Client den ganzen Pool erschöpfen kann. """ global _async_redis_client if _async_redis_client is None: import redis.asyncio as aioredis from app.core.config import settings url = getattr(settings, "redis_url", "redis://localhost:6379/0") - _async_redis_client = aioredis.from_url(url, decode_responses=True) + _async_redis_client = aioredis.from_url( + url, + decode_responses=True, + socket_connect_timeout=2, + socket_timeout=5, + max_connections=50, + ) + log.info("Async-Redis-Pool erstellt: %s (max_connections=50)", url) return _async_redis_client diff --git a/backend/app/main.py b/backend/app/main.py index ce9c152..a53aece 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -52,6 +52,17 @@ async def lifespan(app: FastAPI): from app.services.scheduler_service import start as start_scheduler start_scheduler() + # Async-Redis-Pool: einmaliger Ping beim Start, nur zur Sichtbarkeit im Log + # (Sessions/Lockouts/Nonce-Cache brauchen Redis, App startet aber auch ohne – + # Fehler zeigen sich dann erst beim ersten Request, siehe get_async_redis()). + if "pytest" not in sys.modules: + from app.core.redis import get_async_redis + try: + await get_async_redis().ping() + _log.info("Async-Redis-Pool: Verbindung beim Start OK.") + except Exception as exc: + _log.warning("Async-Redis-Pool: kein Redis beim Start erreichbar (%s).", exc) + yield # Shutdown from app.services.scheduler_service import shutdown as shutdown_scheduler