cuatrolabs-auth-ms / app /cache.py
MukeshKapoor25's picture
feat(logging): Enhance logging with structured events and error handling
17ba139
"""
Cache module for Auth microservice - Redis connection and caching utilities
"""
import redis
from typing import Optional, Any
import json
from app.core.config import settings
from app.core.logging import get_logger
logger = get_logger(__name__)
class CacheService:
"""Redis cache service for authentication system"""
def __init__(self):
self._redis_client: Optional[redis.Redis] = None
def get_client(self) -> redis.Redis:
"""Get Redis client instance with connection pooling"""
if self._redis_client is None:
# Build connection pool parameters
pool_params = {
"host": settings.REDIS_HOST,
"port": settings.REDIS_PORT,
"db": settings.REDIS_DB,
"decode_responses": True,
"max_connections": 10,
"socket_keepalive": True,
"socket_connect_timeout": 5,
"retry_on_timeout": True,
"health_check_interval": 30
}
# Only add password if it's set
if settings.REDIS_PASSWORD:
pool_params["password"] = settings.REDIS_PASSWORD
pool = redis.ConnectionPool(**pool_params)
self._redis_client = redis.Redis(connection_pool=pool)
logger.info(
"Redis connected",
extra={
"event": "redis_connected",
"redis_host": settings.REDIS_HOST,
"redis_port": settings.REDIS_PORT,
"redis_db": settings.REDIS_DB,
},
)
return self._redis_client
async def set(self, key: str, value: Any, ttl: int = 300) -> bool:
"""Set a value in cache with TTL"""
try:
client = self.get_client()
serialized_value = json.dumps(value) if not isinstance(value, str) else value
return client.setex(key, ttl, serialized_value)
except Exception:
logger.error("Cache set failed", exc_info=True, extra={"event": "cache_set_failure", "key": key})
return False
async def get(self, key: str) -> Optional[Any]:
"""Get a value from cache"""
try:
client = self.get_client()
value = client.get(key)
if value:
try:
return json.loads(value)
except json.JSONDecodeError:
return value
return None
except Exception:
logger.error("Cache get failed", exc_info=True, extra={"event": "cache_get_failure", "key": key})
return None
async def delete(self, key: str) -> bool:
"""Delete a key from cache"""
try:
client = self.get_client()
return client.delete(key) > 0
except Exception:
logger.error(
"Cache delete failed",
exc_info=True,
extra={"event": "cache_delete_failure", "key": key},
)
return False
# Global cache instance
cache_service = CacheService()