File size: 1,722 Bytes
9513328 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | """Database connection pooling — Redis + Postgres with auto-reconnect."""
import logging
import os
logger = logging.getLogger(__name__)
REDIS_URL = os.getenv("REDIS_URL", "redis://localhost:6379/0")
PG_URL = os.getenv("DATABASE_URL", "postgresql://postgres:postgres@localhost:5432/postgres")
_redis_pool = None
_pg_pool = None
def get_redis():
"""Get or create Redis connection pool. Auto-reconnects."""
global _redis_pool
if _redis_pool is None:
import redis
try:
_redis_pool = redis.ConnectionPool.from_url(
REDIS_URL, max_connections=20, retry_on_timeout=True, health_check_interval=30
)
logger.info("Redis pool created (max 20)")
except Exception as e:
logger.error(f"Redis pool failed: {e}")
return None
import redis
return redis.Redis(connection_pool=_redis_pool)
def get_postgres():
"""Get or create Postgres connection pool."""
global _pg_pool
if _pg_pool is None:
try:
from psycopg2 import pool
_pg_pool = pool.ThreadedConnectionPool(5, 20, PG_URL)
logger.info("Postgres pool created (5-20)")
except Exception as e:
logger.error(f"Postgres pool failed: {e}")
return None
return _pg_pool.getconn()
def return_postgres(conn):
"""Return connection to pool."""
if _pg_pool and conn:
_pg_pool.putconn(conn)
def pool_stats() -> dict:
"""Get connection pool statistics."""
return {
"redis": {"pool_size": 20, "active": "unknown"} if _redis_pool else {"error": "no pool"},
"postgres": {"min": 5, "max": 20} if _pg_pool else {"error": "no pool"},
}
|