mirror of
https://github.com/open-webui/open-webui.git
synced 2026-09-12 23:02:35 +00:00
fix(redis): add opt-in TCP socket keepalive on all client connections
Introduces REDIS_SOCKET_KEEPALIVE and wires socket_keepalive=True through to every Redis client created by get_redis_connection (plain, cluster and sentinel paths, sync and async). When enabled, the kernel sends TCP keepalive probes on idle connections so half-closed sockets (e.g. after a silent firewall/LB reset or a NIC flap) are detected before the next command lands on them and the request never sees a "Connection reset by peer" error. Defaults to off so existing deployments see no behavioural change. Operators who want the protection set REDIS_SOCKET_KEEPALIVE=true in their environment.
This commit is contained in:
parent
008cd8e6b9
commit
cd087b5368
2 changed files with 20 additions and 0 deletions
|
|
@ -426,6 +426,15 @@ try:
|
|||
except ValueError:
|
||||
REDIS_SOCKET_CONNECT_TIMEOUT = None
|
||||
|
||||
# Whether to enable TCP SO_KEEPALIVE on Redis client sockets. Opt-in:
|
||||
# defaults to off so behavior is unchanged for existing deployments. When
|
||||
# enabled, the kernel sends TCP keepalive probes on idle connections so
|
||||
# half-closed sockets (e.g. after a silent firewall/LB reset or a NIC
|
||||
# flap) are detected before the next command lands on them.
|
||||
REDIS_SOCKET_KEEPALIVE = (
|
||||
os.environ.get('REDIS_SOCKET_KEEPALIVE', 'False').lower() == 'true'
|
||||
)
|
||||
|
||||
REDIS_RECONNECT_DELAY = os.environ.get('REDIS_RECONNECT_DELAY', '')
|
||||
|
||||
if REDIS_RECONNECT_DELAY == '':
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import redis
|
|||
from open_webui.env import (
|
||||
REDIS_CLUSTER,
|
||||
REDIS_SOCKET_CONNECT_TIMEOUT,
|
||||
REDIS_SOCKET_KEEPALIVE,
|
||||
REDIS_SENTINEL_HOSTS,
|
||||
REDIS_SENTINEL_MAX_RETRY_COUNT,
|
||||
REDIS_SENTINEL_PORT,
|
||||
|
|
@ -197,6 +198,10 @@ def get_redis_connection(
|
|||
else {}
|
||||
)
|
||||
|
||||
keepalive_kwargs = (
|
||||
{'socket_keepalive': True} if REDIS_SOCKET_KEEPALIVE else {}
|
||||
)
|
||||
|
||||
if async_mode:
|
||||
import redis.asyncio as redis
|
||||
|
||||
|
|
@ -211,6 +216,7 @@ def get_redis_connection(
|
|||
password=redis_config['password'],
|
||||
decode_responses=decode_responses,
|
||||
socket_connect_timeout=REDIS_SOCKET_CONNECT_TIMEOUT,
|
||||
**keepalive_kwargs,
|
||||
)
|
||||
connection = SentinelRedisProxy(
|
||||
sentinel,
|
||||
|
|
@ -224,12 +230,14 @@ def get_redis_connection(
|
|||
redis_url,
|
||||
decode_responses=decode_responses,
|
||||
**connect_timeout_kwargs,
|
||||
**keepalive_kwargs,
|
||||
)
|
||||
elif redis_url:
|
||||
connection = redis.from_url(
|
||||
redis_url,
|
||||
decode_responses=decode_responses,
|
||||
**connect_timeout_kwargs,
|
||||
**keepalive_kwargs,
|
||||
)
|
||||
else:
|
||||
import redis
|
||||
|
|
@ -244,6 +252,7 @@ def get_redis_connection(
|
|||
password=redis_config['password'],
|
||||
decode_responses=decode_responses,
|
||||
socket_connect_timeout=REDIS_SOCKET_CONNECT_TIMEOUT,
|
||||
**keepalive_kwargs,
|
||||
)
|
||||
connection = SentinelRedisProxy(
|
||||
sentinel,
|
||||
|
|
@ -257,12 +266,14 @@ def get_redis_connection(
|
|||
redis_url,
|
||||
decode_responses=decode_responses,
|
||||
**connect_timeout_kwargs,
|
||||
**keepalive_kwargs,
|
||||
)
|
||||
elif redis_url:
|
||||
connection = redis.Redis.from_url(
|
||||
redis_url,
|
||||
decode_responses=decode_responses,
|
||||
**connect_timeout_kwargs,
|
||||
**keepalive_kwargs,
|
||||
)
|
||||
|
||||
_CONNECTION_CACHE[cache_key] = connection
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue