Spaces:
Sleeping
Sleeping
File size: 4,333 Bytes
f171e60 | 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 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | from typing import Optional, Any, Dict
import json
import redis.asyncio as redis
from app.core.cache.base import BaseCache
from app.config import settings
from app.utils.logger import logger
class RedisCache(BaseCache):
"""
Redis cache implementation
"""
def __init__(self):
"""Initialize Redis cache"""
self.ttl = settings.CACHE_TTL
self._client: Optional[redis.Redis] = None
async def _get_client(self) -> redis.Redis:
"""Get hoặc create Redis client"""
if self._client is None:
try:
self._client = redis.Redis(
host=settings.REDIS_HOST,
port=settings.REDIS_PORT,
db=settings.REDIS_DB,
password=settings.REDIS_PASSWORD,
decode_responses=True
)
# Test connection
await self._client.ping()
logger.info(
f"Redis cache initialized",
extra={
"host": settings.REDIS_HOST,
"port": settings.REDIS_PORT
}
)
except Exception as e:
logger.error(f"Redis connection failed: {e}")
raise
return self._client
async def get(self, key: str) -> Optional[Any]:
"""Get value từ Redis"""
try:
client = await self._get_client()
value = await client.get(key)
if value is not None:
logger.debug(f"Redis cache hit: {key}")
return json.loads(value)
else:
logger.debug(f"Redis cache miss: {key}")
return None
except Exception as e:
logger.error(f"Redis get error: {e}")
return None
async def set(self, key: str, value: Any, ttl: Optional[int] = None) -> bool:
"""Set value vào Redis"""
try:
client = await self._get_client()
ttl = ttl or self.ttl
# Serialize value to JSON
serialized = json.dumps(value)
await client.setex(key, ttl, serialized)
logger.debug(f"Redis cache set: {key} (TTL: {ttl}s)")
return True
except Exception as e:
logger.error(f"Redis set error: {e}")
return False
async def delete(self, key: str) -> bool:
"""Delete key từ Redis"""
try:
client = await self._get_client()
result = await client.delete(key)
logger.debug(f"Redis cache delete: {key}")
return result > 0
except Exception as e:
logger.error(f"Redis delete error: {e}")
return False
async def clear(self) -> bool:
"""Clear toàn bộ cache (FLUSHDB)"""
try:
client = await self._get_client()
await client.flushdb()
logger.info("Redis cache cleared")
return True
except Exception as e:
logger.error(f"Redis clear error: {e}")
return False
async def exists(self, key: str) -> bool:
"""Check key tồn tại"""
try:
client = await self._get_client()
result = await client.exists(key)
return result > 0
except Exception as e:
logger.error(f"Redis exists error: {e}")
return False
async def get_stats(self) -> Dict[str, Any]:
"""Get Redis statistics"""
try:
client = await self._get_client()
info = await client.info()
return {
"type": "redis",
"connected": True,
"keys": await client.dbsize(),
"memory_used": info.get("used_memory_human"),
"uptime": info.get("uptime_in_seconds")
}
except Exception as e:
logger.error(f"Redis stats error: {e}")
return {"type": "redis", "connected": False, "error": str(e)}
async def close(self):
"""Close Redis connection"""
if self._client:
await self._client.close()
logger.info("Redis connection closed") |