| 7 | |
| 8 | |
| 9 | class RedisBackend(Backend): |
| 10 | def __init__(self, redis: Union["Redis[bytes]", "RedisCluster[bytes]"]): |
| 11 | self.redis = redis |
| 12 | self.is_cluster: bool = isinstance(redis, RedisCluster) |
| 13 | |
| 14 | async def get_with_ttl(self, key: str) -> Tuple[int, Optional[bytes]]: |
| 15 | async with self.redis.pipeline(transaction=not self.is_cluster) as pipe: |
| 16 | return await pipe.ttl(key).get(key).execute() # type: ignore[union-attr,no-any-return] |
| 17 | |
| 18 | async def get(self, key: str) -> Optional[bytes]: |
| 19 | return await self.redis.get(key) # type: ignore[union-attr] |
| 20 | |
| 21 | async def set(self, key: str, value: bytes, expire: Optional[int] = None) -> None: |
| 22 | await self.redis.set(key, value, ex=expire) # type: ignore[union-attr] |
| 23 | |
| 24 | async def clear(self, namespace: Optional[str] = None, key: Optional[str] = None) -> int: |
| 25 | if namespace: |
| 26 | lua = f"for i, name in ipairs(redis.call('KEYS', '{namespace}:*')) do redis.call('DEL', name); end" |
| 27 | return await self.redis.eval(lua, numkeys=0) # type: ignore[union-attr,no-any-return] |
| 28 | elif key: |
| 29 | return await self.redis.delete(key) # type: ignore[union-attr] |
| 30 | return 0 |