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