fix(redis): add opt-in health_check_interval for stale pooled connections (#23573)
Introduces REDIS_HEALTH_CHECK_INTERVAL and wires it through to every Redis client created by get_redis_connection (plain, cluster and sentinel paths, sync and async). When set, redis-py will PING any connection idle longer than the interval on checkout, so dead sockets are surfaced as reconnectable errors before a real command lands on them. Defaults to unset (empty string) so existing deployments see no behavioural change. Operators who want the protection should set it shorter than the Redis server `timeout` setting and any firewall/LB idle timeout on the path to Redis. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import redis
|
||||
|
||||
from open_webui.env import (
|
||||
REDIS_CLUSTER,
|
||||
REDIS_HEALTH_CHECK_INTERVAL,
|
||||
REDIS_SOCKET_CONNECT_TIMEOUT,
|
||||
REDIS_SOCKET_KEEPALIVE,
|
||||
REDIS_SENTINEL_HOSTS,
|
||||
@@ -202,6 +203,12 @@ def get_redis_connection(
|
||||
{'socket_keepalive': True} if REDIS_SOCKET_KEEPALIVE else {}
|
||||
)
|
||||
|
||||
health_check_kwargs = (
|
||||
{'health_check_interval': REDIS_HEALTH_CHECK_INTERVAL}
|
||||
if REDIS_HEALTH_CHECK_INTERVAL
|
||||
else {}
|
||||
)
|
||||
|
||||
if async_mode:
|
||||
import redis.asyncio as redis
|
||||
|
||||
@@ -217,6 +224,7 @@ def get_redis_connection(
|
||||
decode_responses=decode_responses,
|
||||
socket_connect_timeout=REDIS_SOCKET_CONNECT_TIMEOUT,
|
||||
**keepalive_kwargs,
|
||||
**health_check_kwargs,
|
||||
)
|
||||
connection = SentinelRedisProxy(
|
||||
sentinel,
|
||||
@@ -231,6 +239,7 @@ def get_redis_connection(
|
||||
decode_responses=decode_responses,
|
||||
**connect_timeout_kwargs,
|
||||
**keepalive_kwargs,
|
||||
**health_check_kwargs,
|
||||
)
|
||||
elif redis_url:
|
||||
connection = redis.from_url(
|
||||
@@ -238,6 +247,7 @@ def get_redis_connection(
|
||||
decode_responses=decode_responses,
|
||||
**connect_timeout_kwargs,
|
||||
**keepalive_kwargs,
|
||||
**health_check_kwargs,
|
||||
)
|
||||
else:
|
||||
import redis
|
||||
@@ -253,6 +263,7 @@ def get_redis_connection(
|
||||
decode_responses=decode_responses,
|
||||
socket_connect_timeout=REDIS_SOCKET_CONNECT_TIMEOUT,
|
||||
**keepalive_kwargs,
|
||||
**health_check_kwargs,
|
||||
)
|
||||
connection = SentinelRedisProxy(
|
||||
sentinel,
|
||||
@@ -267,6 +278,7 @@ def get_redis_connection(
|
||||
decode_responses=decode_responses,
|
||||
**connect_timeout_kwargs,
|
||||
**keepalive_kwargs,
|
||||
**health_check_kwargs,
|
||||
)
|
||||
elif redis_url:
|
||||
connection = redis.Redis.from_url(
|
||||
@@ -274,6 +286,7 @@ def get_redis_connection(
|
||||
decode_responses=decode_responses,
|
||||
**connect_timeout_kwargs,
|
||||
**keepalive_kwargs,
|
||||
**health_check_kwargs,
|
||||
)
|
||||
|
||||
_CONNECTION_CACHE[cache_key] = connection
|
||||
|
||||
Reference in New Issue
Block a user