fix: Use an async client for Redis cache (#4231)

Use an async client for Redis cache
This commit is contained in:
Christophe Bornet 2024-10-21 23:16:06 +02:00 • committed by GitHub
commit 349a2b49a4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -197,7 +197,7 @@ class RedisCache(AsyncBaseCacheService, Generic[LockType]):
cached item expires. Default is 1 hour. cached item expires. Default is 1 hour.
""" """
try: try:
import redis from redis.asyncio import StrictRedis
except ImportError as exc: except ImportError as exc:
msg = ( msg = (
"RedisCache requires the redis-py package." "RedisCache requires the redis-py package."
@ -209,9 +209,9 @@ class RedisCache(AsyncBaseCacheService, Generic[LockType]):
" Please report any issues to our GitHub repository." " Please report any issues to our GitHub repository."
) )
if url: if url:
self._client = redis.StrictRedis.from_url(url) self._client = StrictRedis.from_url(url)
else: else:
self._client = redis.StrictRedis(host=host, port=port, db=db) self._client = StrictRedis(host=host, port=port, db=db)
self.expiration_time = expiration_time self.expiration_time = expiration_time
# check connection # check connection
@ -220,7 +220,7 @@ class RedisCache(AsyncBaseCacheService, Generic[LockType]):
import redis import redis
try: try:
self._client.ping() asyncio.run(self._client.ping())
except redis.exceptions.ConnectionError: except redis.exceptions.ConnectionError:
logger.exception("RedisCache could not connect to the Redis server") logger.exception("RedisCache could not connect to the Redis server")
return False return False
@ -230,14 +230,14 @@ class RedisCache(AsyncBaseCacheService, Generic[LockType]):
async def get(self, key, lock=None): async def get(self, key, lock=None):
if key is None: if key is None:
return None return None
value = self._client.get(str(key)) value = await self._client.get(str(key))
return pickle.loads(value) if value else None return pickle.loads(value) if value else None
@override @override
async def set(self, key, value, lock=None): async def set(self, key, value, lock=None):
try: try:
if pickled := pickle.dumps(value): if pickled := pickle.dumps(value):
result = self._client.setex(str(key), self.expiration_time, pickled) result = await self._client.setex(str(key), self.expiration_time, pickled)
if not result: if not result:
msg = "RedisCache could not set the value." msg = "RedisCache could not set the value."
raise ValueError(msg) raise ValueError(msg)
@ -267,28 +267,18 @@ class RedisCache(AsyncBaseCacheService, Generic[LockType]):
@override @override
async def delete(self, key, lock=None): async def delete(self, key, lock=None):
self._client.delete(key) await self._client.delete(key)
@override @override
async def clear(self, lock=None): async def clear(self, lock=None):
"""Clear all items from the cache.""" """Clear all items from the cache."""
self._client.flushdb() await self._client.flushdb()
def __contains__(self, key): def __contains__(self, key):
"""Check if the key is in the cache.""" """Check if the key is in the cache."""
return False if key is None else self._client.exists(str(key)) if key is None:
return False
async def __getitem__(self, key): return asyncio.run(self._client.exists(str(key)))
"""Retrieve an item from the cache using the square bracket notation."""
return self.get(key)
async def __setitem__(self, key, value):
"""Add an item to the cache using the square bracket notation."""
self.set(key, value)
async def __delitem__(self, key):
"""Remove an item from the cache using the square bracket notation."""
self.delete(key)
def __repr__(self): def __repr__(self):
"""Return a string representation of the RedisCache instance.""" """Return a string representation of the RedisCache instance."""