File size: 2,860 Bytes
b407a42
 
6e5d529
b407a42
 
 
 
 
 
 
 
6e5d529
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b407a42
 
6e5d529
 
 
b407a42
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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