Enable automatic retry on redis errors (#4595)

* Enable automatic retry on redis errors

ExponentialBackoff 3x retry for BusyLoadingError, ConnectionError, and TimeoutError

* retry on any redis error

* Use default single-retry for any RedisError

Using the default Retry means that async and sync clients get the appropriate type of Retry
This commit is contained in:
Masen Furer 2025-01-07 10:24:43 -08:00 committed by GitHub
parent eae15e3a83
commit 72d7616726
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -28,8 +28,8 @@ import typer
from alembic.util.exc import CommandError from alembic.util.exc import CommandError
from packaging import version from packaging import version
from redis import Redis as RedisSync from redis import Redis as RedisSync
from redis import exceptions
from redis.asyncio import Redis from redis.asyncio import Redis
from redis.exceptions import RedisError
from reflex import constants, model from reflex import constants, model
from reflex.compiler import templates from reflex.compiler import templates
@ -333,10 +333,11 @@ def get_redis() -> Redis | None:
Returns: Returns:
The asynchronous redis client. The asynchronous redis client.
""" """
if isinstance((redis_url_or_options := parse_redis_url()), str): if (redis_url := parse_redis_url()) is not None:
return Redis.from_url(redis_url_or_options) return Redis.from_url(
elif isinstance(redis_url_or_options, dict): redis_url,
return Redis(**redis_url_or_options) retry_on_error=[RedisError],
)
return None return None
@ -346,14 +347,15 @@ def get_redis_sync() -> RedisSync | None:
Returns: Returns:
The synchronous redis client. The synchronous redis client.
""" """
if isinstance((redis_url_or_options := parse_redis_url()), str): if (redis_url := parse_redis_url()) is not None:
return RedisSync.from_url(redis_url_or_options) return RedisSync.from_url(
elif isinstance(redis_url_or_options, dict): redis_url,
return RedisSync(**redis_url_or_options) retry_on_error=[RedisError],
)
return None return None
def parse_redis_url() -> str | dict | None: def parse_redis_url() -> str | None:
"""Parse the REDIS_URL in config if applicable. """Parse the REDIS_URL in config if applicable.
Returns: Returns:
@ -387,7 +389,7 @@ async def get_redis_status() -> dict[str, bool | None]:
redis_client.ping() redis_client.ping()
else: else:
status = None status = None
except exceptions.RedisError: except RedisError:
status = False status = False
return {"redis": status} return {"redis": status}