fix(redis): default every Redis client to a 5s socket timeout when none is set (#46501)

* fix(redis): raise the Sentinel socket timeout default from 0.1s to 5s

Sentinel clients built without an explicit socket_timeout fell back to REDIS_SOCKET_TIMEOUT, which defaulted to 100 ms. That is short enough for a cross-AZ hop, TLS, or a brief Redis pause to raise a timeout. 5s matches the RedisCache default and redis-py 8.x.

* test(redis): drop the Sentinel default socket timeout test

* fix(redis): default every Redis client to a 5s socket timeout when none is set

Plain host, url and cluster clients built without socket_timeout (including cache_params socket_timeout: null) fell through to redis-py's None and blocked forever on a hung Redis. The REDIS_SOCKET_TIMEOUT fallback now lives in _get_redis_client_logic, which every sync, async, pool, cluster and Sentinel path goes through, replacing the Sentinel-only setdefaults
This commit is contained in:
ryan-crabbe-berri 2026-10-14 15:00:03 -07:00 • committed by GitHub
parent f76f7e1368
commit c30b90c1ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 5 additions and 4 deletions

View file

@ -675,7 +675,10 @@ def _get_redis_client_logic(**env_overrides):
if redis_kwargs.get("startup_nodes")
else redis.Redis
)
return _coerce_redis_kwargs_types(redis_kwargs, client=coercion_client)
coerced_kwargs: Final = _coerce_redis_kwargs_types(redis_kwargs, client=coercion_client)
if coerced_kwargs.get("socket_timeout") is None:
coerced_kwargs["socket_timeout"] = REDIS_SOCKET_TIMEOUT
return coerced_kwargs
def init_redis_cluster(redis_kwargs) -> redis.RedisCluster:
@ -722,7 +725,6 @@ def _init_redis_sentinel(redis_kwargs) -> redis.Redis:
sentinel_password: Final = redis_kwargs.get("sentinel_password")
service_name: Final = redis_kwargs.get("service_name")
connection_kwargs: Final = _get_redis_sentinel_connection_kwargs(redis_kwargs)
connection_kwargs.setdefault("socket_timeout", REDIS_SOCKET_TIMEOUT)
sentinel_kwargs: Final = _sentinel_auth_kwargs(connection_kwargs, sentinel_password)
if not sentinel_nodes or not service_name:
@ -755,7 +757,6 @@ def _init_async_redis_sentinel(redis_kwargs) -> async_redis.Redis:
sentinel_password: Final = redis_kwargs.get("sentinel_password")
service_name: Final = redis_kwargs.get("service_name")
connection_kwargs: Final = _get_redis_sentinel_connection_kwargs(redis_kwargs)
connection_kwargs.setdefault("socket_timeout", REDIS_SOCKET_TIMEOUT)
sentinel_kwargs: Final = _sentinel_auth_kwargs(connection_kwargs, sentinel_password)
if not sentinel_nodes or not service_name:

View file

@ -551,7 +551,7 @@ DEFAULT_POLLING_INTERVAL: Final = get_env_float(
AZURE_OPERATION_POLLING_TIMEOUT: Final = get_env_int("AZURE_OPERATION_POLLING_TIMEOUT", 120)
AZURE_DOCUMENT_INTELLIGENCE_API_VERSION: Final = str(os.getenv("AZURE_DOCUMENT_INTELLIGENCE_API_VERSION", "2024-11-30"))
AZURE_DOCUMENT_INTELLIGENCE_DEFAULT_DPI: Final = get_env_int("AZURE_DOCUMENT_INTELLIGENCE_DEFAULT_DPI", 96)
REDIS_SOCKET_TIMEOUT: Final = get_env_float("REDIS_SOCKET_TIMEOUT", 0.1)
REDIS_SOCKET_TIMEOUT: Final = get_env_float("REDIS_SOCKET_TIMEOUT", 5.0)
CACHE_WRITE_SHUTDOWN_FLUSH_TIMEOUT_SECONDS: Final[float] = 5.0
REDIS_CONNECTION_POOL_TIMEOUT: Final = get_env_int("REDIS_CONNECTION_POOL_TIMEOUT", 5)
REDIS_CIRCUIT_BREAKER_FAILURE_THRESHOLD: Final = get_env_int("REDIS_CIRCUIT_BREAKER_FAILURE_THRESHOLD", 5)