Spaces:
Running
Running
File size: 2,356 Bytes
409c17a |
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 |
"""
Infrastructure - Redis Cache Implementation
"""
import json
from typing import Any, Optional
import redis.asyncio as redis
from app.domain.interfaces import ICache
class RedisCache(ICache):
"""Redis cache implementation"""
def __init__(self, redis_url: str):
self.redis_url = redis_url
self._client: Optional[redis.Redis] = None
async def _get_client(self) -> redis.Redis:
"""Get or create Redis client"""
if self._client is None:
self._client = await redis.from_url(
self.redis_url, encoding="utf-8", decode_responses=True
)
return self._client
async def get(self, key: str) -> Optional[Any]:
"""Get value from cache"""
client = await self._get_client()
value = await client.get(key)
if value is None:
return None
try:
return json.loads(value)
except json.JSONDecodeError:
return value
async def set(self, key: str, value: Any, ttl: Optional[int] = None) -> bool:
"""Set value in cache"""
client = await self._get_client()
# Serialize value
if isinstance(value, (dict, list)):
serialized = json.dumps(value)
else:
serialized = str(value)
if ttl:
await client.setex(key, ttl, serialized)
else:
await client.set(key, serialized)
return True
async def delete(self, key: str) -> bool:
"""Delete key from cache"""
client = await self._get_client()
result = await client.delete(key)
return result > 0
async def exists(self, key: str) -> bool:
"""Check if key exists"""
client = await self._get_client()
return await client.exists(key) > 0
async def clear(self, pattern: str = "*") -> int:
"""Clear cache by pattern"""
client = await self._get_client()
keys = []
async for key in client.scan_iter(match=pattern):
keys.append(key)
if keys:
return await client.delete(*keys)
return 0
async def close(self) -> None:
"""Close Redis connection"""
if self._client:
await self._client.close()
|