bookmyservice-ums / app /core /cache_client.py
MukeshKapoor25's picture
refactor(cache): improve redis client initialization with better error handling
6e5d529
import logging
from redis.asyncio import Redis
from redis.exceptions import RedisError, ConnectionError, AuthenticationError
from app.core.config import settings
logger = logging.getLogger(__name__)
# Parse host and port
CACHE_HOST, CACHE_PORT = settings.CACHE_URI.split(":")
CACHE_PORT = int(CACHE_PORT)
async def create_redis_client():
"""Create Redis client with proper error handling and fallback"""
try:
# First try with authentication if password is provided
if settings.CACHE_K and settings.CACHE_K.strip():
redis_client = Redis(
host=CACHE_HOST,
port=CACHE_PORT,
username="default",
password=settings.CACHE_K,
decode_responses=True,
socket_connect_timeout=5,
socket_timeout=5,
retry_on_timeout=True
)
# Test the connection
await redis_client.ping()
logger.info(f"Connected to Redis at {CACHE_HOST}:{CACHE_PORT} with authentication")
return redis_client
else:
# Try without authentication for local Redis
redis_client = Redis(
host=CACHE_HOST,
port=CACHE_PORT,
decode_responses=True,
socket_connect_timeout=5,
socket_timeout=5,
retry_on_timeout=True
)
# Test the connection
await redis_client.ping()
logger.info(f"Connected to Redis at {CACHE_HOST}:{CACHE_PORT} without authentication")
return redis_client
except AuthenticationError as e:
logger.warning(f"Authentication failed for Redis: {e}")
# Try without authentication as fallback
try:
redis_client = Redis(
host=CACHE_HOST,
port=CACHE_PORT,
decode_responses=True,
socket_connect_timeout=5,
socket_timeout=5,
retry_on_timeout=True
)
await redis_client.ping()
logger.info(f"Connected to Redis at {CACHE_HOST}:{CACHE_PORT} without authentication (fallback)")
return redis_client
except Exception as fallback_error:
logger.error(f"Redis fallback connection also failed: {fallback_error}")
raise
except ConnectionError as e:
logger.error(f"Failed to connect to Redis at {CACHE_HOST}:{CACHE_PORT}: {e}")
raise
except Exception as e:
logger.error(f"Unexpected error connecting to Redis: {e}")
raise
# Initialize Redis client
redis_client = None
async def get_redis() -> Redis:
global redis_client
if redis_client is None:
redis_client = await create_redis_client()
return redis_client