import json import time from utils.config import config # Try to import redis, but handle if not available try: import redis REDIS_AVAILABLE = True except ImportError: REDIS_AVAILABLE = False redis = None def get_redis_client(): """Create and return Redis client with retry logic""" if not REDIS_AVAILABLE: return None last_exception = None for attempt in range(config.redis_retries + 1): try: # Handle empty username/password gracefully redis_client = redis.Redis( host=config.redis_host, port=config.redis_port, username=config.redis_username if config.redis_username else None, password=config.redis_password if config.redis_password else None, decode_responses=True, socket_connect_timeout=5, socket_timeout=5 ) # Test the connection redis_client.ping() return redis_client except Exception as e: last_exception = e if attempt < config.redis_retries: time.sleep(config.redis_retry_delay * (2 ** attempt)) # Exponential backoff continue return None # Initialize Redis connection with better error handling redis_client = None try: redis_client = get_redis_client() if redis_client is None and REDIS_AVAILABLE: print("Warning: Could not connect to Redis - using in-memory storage") except Exception as e: print(f"Warning: Redis initialization failed: {e}") def save_user_state(user_id: str, state: dict): """Save user state to Redis with fallback to in-memory storage""" global redis_client if not redis_client: # Fallback: use in-memory storage (will not persist across restarts) print("Redis not available, using in-memory storage for user state") return False try: redis_client.hset(f"user:{user_id}", mapping=state) return True except Exception as e: print(f"Error saving user state: {e}") return False def load_user_state(user_id: str): """Load user state from Redis with fallback""" global redis_client if not redis_client: print("Redis not available, returning empty state") return {} try: return redis_client.hgetall(f"user:{user_id}") except Exception as e: print(f"Error loading user state: {e}") return {} def check_redis_health(): """Check if Redis is healthy""" global redis_client if not redis_client: return False try: redis_client.ping() return True except: return False