geo/backend/app/core/redis.py

65 lines
1.8 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 连接管理。
提供全局 Redis 连接池单例,所有模块共享同一连接池,
避免多处独立创建连接导致资源浪费和连接数失控。
用法:
from app.core.redis import get_redis
redis = await get_redis()
await redis.set("key", "value")
"""
import logging
import redis.asyncio as aioredis
from app.config import settings
logger = logging.getLogger(__name__)
# 全局 Redis 连接池单例
_redis: aioredis.Redis | None = None
async def get_redis() -> aioredis.Redis:
"""获取全局 Redis 连接。
首次调用时根据 settings.REDIS_URL 创建连接池,
后续调用返回同一实例。REDIS_URL 为空时抛出 ValueError。
"""
global _redis
if _redis is None:
if not settings.REDIS_URL:
raise ValueError("REDIS_URL is not configured")
_redis = aioredis.from_url(
settings.REDIS_URL,
encoding="utf-8",
decode_responses=True,
)
logger.info("Redis connection pool created (url=%s)", _safe_url(settings.REDIS_URL))
return _redis
async def close_redis() -> None:
"""关闭全局 Redis 连接。在应用 shutdown 时调用。"""
global _redis
if _redis is not None:
await _redis.aclose()
_redis = None
logger.info("Redis connection pool closed")
def is_redis_configured() -> bool:
"""检查 Redis 是否已配置REDIS_URL 非空)。"""
return bool(settings.REDIS_URL)
def _safe_url(url: str) -> str:
"""隐藏 Redis URL 中的密码部分。"""
if "@" in url:
# redis://:password@host:port/db → redis://***@host:port/db
parts = url.split("@", 1)
prefix = parts[0].rsplit(":", 1)[0]
return f"{prefix}:***@{parts[1]}"
return url