From 832f42a996a99ceaabbc018f99125c313cf8a638 Mon Sep 17 00:00:00 2001 From: Checo <104541981+sergioperezcheco@users.noreply.github.com> Date: Thu, 30 Jul 2026 08:50:21 +0800 Subject: [PATCH] fix(socketio): omit socket_timeout from RedisManager pub/sub options (#39587) Signed-off-by: sergioperezcheco --- api/extensions/ext_socketio.py | 9 +++++++-- api/tests/unit_tests/extensions/test_ext_socketio.py | 12 ++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/api/extensions/ext_socketio.py b/api/extensions/ext_socketio.py index 887734c8b8d..78ff7576287 100644 --- a/api/extensions/ext_socketio.py +++ b/api/extensions/ext_socketio.py @@ -20,9 +20,14 @@ def _get_ssl_cert_reqs() -> ssl.VerifyMode: def _build_redis_options(redis_url: str) -> dict[str, Any]: - """Build Redis options for Socket.IO's cross-process pub/sub manager.""" + """Build Redis options for Socket.IO's cross-process pub/sub manager. + + Note: ``socket_timeout`` is intentionally omitted. The RedisManager runs a + blocking ``pubsub.listen()`` loop that idles indefinitely between messages; + applying a read timeout there causes a reconnect storm (issue #39423). + ``socket_connect_timeout`` still guards connection establishment. + """ options: dict[str, Any] = { - "socket_timeout": dify_config.REDIS_SOCKET_TIMEOUT, "socket_connect_timeout": dify_config.REDIS_SOCKET_CONNECT_TIMEOUT, "health_check_interval": dify_config.REDIS_HEALTH_CHECK_INTERVAL, "protocol": dify_config.REDIS_SERIALIZATION_PROTOCOL, diff --git a/api/tests/unit_tests/extensions/test_ext_socketio.py b/api/tests/unit_tests/extensions/test_ext_socketio.py index f9f85106960..20271d1516f 100644 --- a/api/tests/unit_tests/extensions/test_ext_socketio.py +++ b/api/tests/unit_tests/extensions/test_ext_socketio.py @@ -31,3 +31,15 @@ def test_build_redis_options_includes_tls_options_for_rediss(monkeypatch) -> Non assert options["ssl_ca_certs"] == "/ca.pem" assert options["ssl_certfile"] == "/cert.pem" assert options["ssl_keyfile"] == "/key.pem" + + +def test_build_redis_options_omits_socket_timeout(monkeypatch) -> None: + # socket_timeout must not be passed to RedisManager because the pub/sub + # listen loop blocks indefinitely between messages; a read timeout there + # triggers an infinite reconnect storm (issue #39423). + monkeypatch.setattr(ext_socketio.dify_config, "REDIS_SOCKET_TIMEOUT", 5.0) + + options = ext_socketio._build_redis_options("redis://redis.example.com:6380/3") + + assert "socket_timeout" not in options + assert "socket_connect_timeout" in options