Files
timemaster/backend/app/core/redis.py
T
patrickandClaude Sonnet 5 c733ddfe40
Security Audit / Python Dependency Audit (push) Canceled after 0s
Security Audit / Node.js Dependency Audit (push) Canceled after 0s
fix(redis): gepoolten async-Redis-Client statt Connect/Close pro Request
TOTP-Login und Kiosk-Nonce-Check öffneten/schlossen bisher pro Request eine
neue aioredis-Verbindung. Neuer get_async_redis()-Pool in core/redis.py wird
von beiden Stellen genutzt, sauberer Shutdown im FastAPI-Lifespan.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Ahyx6D3r7G1EuAc42nezn
2026-09-02 22:29:08 +02:00

55 lines
2.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Redis-Client für TimeMaster (sync + async, für Kiosk-Nonce-Cache, Sessions, Locks)."""
from __future__ import annotations
import logging
from typing import Optional
log = logging.getLogger(__name__)
_redis_client = None
_async_redis_client = None
def get_redis_client():
"""Gibt den (sync) Redis-Client zurück oder None wenn nicht konfiguriert/erreichbar."""
global _redis_client
if _redis_client is not None:
return _redis_client
try:
import redis as redis_lib
from app.core.config import settings
url = getattr(settings, "redis_url", "redis://localhost:6379/0")
_redis_client = redis_lib.from_url(url, decode_responses=True, socket_connect_timeout=2)
# Verbindung testen
_redis_client.ping()
log.info("Redis-Verbindung hergestellt: %s", url)
return _redis_client
except Exception as exc:
log.warning("Redis nicht verfügbar: %s", exc)
return None
def get_async_redis():
"""Gepoolter async Redis-Client (eine Verbindungspool-Instanz pro Prozess).
Nicht pro Request neu verbinden/schließen (frühere Falle in totp_login und
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).
"""
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)
return _async_redis_client
async def close_async_redis() -> None:
"""Pool sauber schließen im FastAPI-Lifespan-Shutdown aufrufen."""
global _async_redis_client
if _async_redis_client is not None:
await _async_redis_client.aclose()
_async_redis_client = None