Skip to content

Commit 588b81e

Browse files
Classic298claude
andauthored
fix(redis): add opt-in health_check_interval for stale pooled connections (open-webui#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>
1 parent db7f122 commit 588b81e

2 files changed

Lines changed: 27 additions & 0 deletions

File tree

backend/open_webui/env.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,20 @@ def parse_section(section):
435435
os.environ.get('REDIS_SOCKET_KEEPALIVE', 'False').lower() == 'true'
436436
)
437437

438+
# How often (in seconds) redis-py should PING an idle pooled connection
439+
# before reusing it. Opt-in: defaults to unset (empty string) so behavior
440+
# is unchanged for existing deployments. When set, should be shorter than
441+
# the Redis server `timeout` setting and any firewall/LB idle timeout on
442+
# the path to Redis, so stale connections are detected before a real
443+
# command lands on them. Set to 0 or empty to disable.
444+
REDIS_HEALTH_CHECK_INTERVAL = os.environ.get('REDIS_HEALTH_CHECK_INTERVAL', '')
445+
try:
446+
REDIS_HEALTH_CHECK_INTERVAL = int(REDIS_HEALTH_CHECK_INTERVAL)
447+
if REDIS_HEALTH_CHECK_INTERVAL <= 0:
448+
REDIS_HEALTH_CHECK_INTERVAL = None
449+
except ValueError:
450+
REDIS_HEALTH_CHECK_INTERVAL = None
451+
438452
REDIS_RECONNECT_DELAY = os.environ.get('REDIS_RECONNECT_DELAY', '')
439453

440454
if REDIS_RECONNECT_DELAY == '':

backend/open_webui/utils/redis.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from open_webui.env import (
1111
REDIS_CLUSTER,
12+
REDIS_HEALTH_CHECK_INTERVAL,
1213
REDIS_SOCKET_CONNECT_TIMEOUT,
1314
REDIS_SOCKET_KEEPALIVE,
1415
REDIS_SENTINEL_HOSTS,
@@ -202,6 +203,12 @@ def get_redis_connection(
202203
{'socket_keepalive': True} if REDIS_SOCKET_KEEPALIVE else {}
203204
)
204205

206+
health_check_kwargs = (
207+
{'health_check_interval': REDIS_HEALTH_CHECK_INTERVAL}
208+
if REDIS_HEALTH_CHECK_INTERVAL
209+
else {}
210+
)
211+
205212
if async_mode:
206213
import redis.asyncio as redis
207214

@@ -217,6 +224,7 @@ def get_redis_connection(
217224
decode_responses=decode_responses,
218225
socket_connect_timeout=REDIS_SOCKET_CONNECT_TIMEOUT,
219226
**keepalive_kwargs,
227+
**health_check_kwargs,
220228
)
221229
connection = SentinelRedisProxy(
222230
sentinel,
@@ -231,13 +239,15 @@ def get_redis_connection(
231239
decode_responses=decode_responses,
232240
**connect_timeout_kwargs,
233241
**keepalive_kwargs,
242+
**health_check_kwargs,
234243
)
235244
elif redis_url:
236245
connection = redis.from_url(
237246
redis_url,
238247
decode_responses=decode_responses,
239248
**connect_timeout_kwargs,
240249
**keepalive_kwargs,
250+
**health_check_kwargs,
241251
)
242252
else:
243253
import redis
@@ -253,6 +263,7 @@ def get_redis_connection(
253263
decode_responses=decode_responses,
254264
socket_connect_timeout=REDIS_SOCKET_CONNECT_TIMEOUT,
255265
**keepalive_kwargs,
266+
**health_check_kwargs,
256267
)
257268
connection = SentinelRedisProxy(
258269
sentinel,
@@ -267,13 +278,15 @@ def get_redis_connection(
267278
decode_responses=decode_responses,
268279
**connect_timeout_kwargs,
269280
**keepalive_kwargs,
281+
**health_check_kwargs,
270282
)
271283
elif redis_url:
272284
connection = redis.Redis.from_url(
273285
redis_url,
274286
decode_responses=decode_responses,
275287
**connect_timeout_kwargs,
276288
**keepalive_kwargs,
289+
**health_check_kwargs,
277290
)
278291

279292
_CONNECTION_CACHE[cache_key] = connection

0 commit comments

Comments
 (0)