71 lines
2.0 KiB
Python
71 lines
2.0 KiB
Python
|
|
"""Redis client wrapper."""
|
||
|
|
|
||
|
|
import redis.asyncio as redis
|
||
|
|
from typing import Optional
|
||
|
|
from src.core.config import get_config
|
||
|
|
from src.core.logger import get_logger
|
||
|
|
|
||
|
|
logger = get_logger(__name__)
|
||
|
|
|
||
|
|
|
||
|
|
class RedisClient:
|
||
|
|
"""Redis client wrapper with automatic connection handling."""
|
||
|
|
|
||
|
|
def __init__(self):
|
||
|
|
"""Initialize Redis client."""
|
||
|
|
self.config = get_config()
|
||
|
|
self._client: Optional[redis.Redis] = None
|
||
|
|
self._pool: Optional[redis.ConnectionPool] = None
|
||
|
|
|
||
|
|
def get_client(self) -> redis.Redis:
|
||
|
|
"""Get or create Redis client.
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Async Redis client
|
||
|
|
"""
|
||
|
|
if self._client is None:
|
||
|
|
self._connect()
|
||
|
|
return self._client
|
||
|
|
|
||
|
|
def _connect(self):
|
||
|
|
"""Connect to Redis."""
|
||
|
|
redis_config = self.config.get("redis", {})
|
||
|
|
host = redis_config.get("host", "localhost")
|
||
|
|
port = redis_config.get("port", 6379)
|
||
|
|
db = redis_config.get("db", 0)
|
||
|
|
password = redis_config.get("password")
|
||
|
|
|
||
|
|
logger.info(f"Connecting to Redis at {host}:{port}/{db}")
|
||
|
|
|
||
|
|
try:
|
||
|
|
self._pool = redis.ConnectionPool(
|
||
|
|
host=host,
|
||
|
|
port=port,
|
||
|
|
db=db,
|
||
|
|
password=password,
|
||
|
|
decode_responses=True,
|
||
|
|
socket_connect_timeout=redis_config.get("socket_connect_timeout", 5)
|
||
|
|
)
|
||
|
|
self._client = redis.Redis(connection_pool=self._pool)
|
||
|
|
except Exception as e:
|
||
|
|
logger.error(f"Failed to create Redis client: {e}")
|
||
|
|
raise
|
||
|
|
|
||
|
|
async def close(self):
|
||
|
|
"""Close Redis connection."""
|
||
|
|
if self._client:
|
||
|
|
await self._client.aclose()
|
||
|
|
logger.info("Redis connection closed")
|
||
|
|
|
||
|
|
|
||
|
|
# Global instance
|
||
|
|
_redis_client: Optional[RedisClient] = None
|
||
|
|
|
||
|
|
|
||
|
|
def get_redis_client() -> RedisClient:
|
||
|
|
"""Get global Redis client instance."""
|
||
|
|
global _redis_client
|
||
|
|
if _redis_client is None:
|
||
|
|
_redis_client = RedisClient()
|
||
|
|
return _redis_client
|