Conversation
…ache-ai#4003) hiredis latches any I/O error onto the redisContext; subsequent commands return nullptr immediately without attempting a new TCP connection. A single idle-timeout TCP drop (e.g. from a load-balancer) therefore permanently disabled the entire metadata publish/query path. Fix: - Save host/port at construction time so the plugin can reconnect. - Store username/password/db_index so re-AUTH and re-SELECT can be issued after reconnect. - Add private reconnect(): redisFree + redisConnect + optional AUTH + optional SELECT. Returns false instead of crashing on failure. - Add ensureConnected(): detects ctx_->err != 0 before each command and calls reconnect() once. - In get/set/remove: call ensureConnected() first; if redisCommand still returns nullptr, attempt one more reconnect-and-retry. - Add RedisStoragePluginTest unit tests (skipped when no Redis server is available; controlled by MC_REDIS_TEST_SERVER env-var). Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
Thanks @XFDG — I filed #4003 and opened #4042 for the same bug before noticing this The two fixes share the same core: remember the connection parameters, rebuild the 1. Connect and command timeouts. This is the part that matters most for the 2. TCP keepalive. The plugin only touches Redis on segment (un)registration and on 3. Tests that actually drop a connection, with no external Redis. The tests here This exact patch is running in production. It has been cherry-picked onto Credit where due: checking Also worth flagging for whichever PR lands: the CI job that runs @alogfans could you advise which route you prefer? Happy to do the work either way. |
|
Thanks for working on this. After comparing this PR with #4042, I prefer moving forward with #4042. The main blocker here is that construction-time failures are still permanent: the authenticated constructor returns before saving the credentials when #4042 also covers connect/command timeouts, TCP keepalive, AUTH/SELECT replay, and deterministic disconnect tests. These are important for the silent load-balancer timeout scenario described in #4003. Thank you for providing the initial implementation and helping clarify the required reconnect behavior. |
Description
Fixes #4003.
RedisStoragePluginholds a single long-livedredisContextand never rebuilds it. hiredis latches any I/O error into the context (ctx->err != 0) and then rejects every subsequent command — so a single disconnect (e.g. a load-balancer idle timeout) permanently disables metadata publishing and lookup for the rest of the process lifetime:Root Cause
RedisStoragePluginnever storedhost/portand had no reconnect path. After anyREDIS_ERR_IO, the stale context was reused indefinitely.Fix
host_,port_,username_,password_,db_index_at construction time.reconnect():redisFree→redisConnect→ optionalAUTH→ optionalSELECT. Returnsfalseon failure (never crashes).ensureConnected(): checksctx->errbefore each operation; callsreconnect()if non-zero.get(),set(),remove(): callensureConnected()first; onnullptrreply, do onereconnect()+ retry (handles mid-flight drops).Testing
RedisStoragePluginTest/BasicRoundTrip: SET/GET/DEL round-trip; skipped viaGTEST_SKIP()whenMC_REDIS_TEST_SERVERis unreachable.RedisStoragePluginTest/PluginWorksAfterInitialConnectionError: verifies gracefulfalse(no crash) when server is unreachable from start.