|
|
import json |
|
|
import time |
|
|
from utils.config import config |
|
|
|
|
|
|
|
|
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: |
|
|
|
|
|
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 |
|
|
) |
|
|
|
|
|
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)) |
|
|
continue |
|
|
|
|
|
return None |
|
|
|
|
|
|
|
|
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: |
|
|
|
|
|
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 |
|
|
|