Skip to content

Remove Redis Cluster support - #132

Merged
derekste merged 1 commit into
mainfrom
dev/remove-cluster-support
Oct 7, 2026
Merged

derekste merged 1 commit into
mainfrom
dev/remove-cluster-support

Conversation

@derekste

@derekste derekste commented Oct 7, 2026

Copy link
Copy Markdown
Member

Summary

  • replace Redis Cluster clients and slot routing with standalone command and reader clients
  • classify the first reachable endpoint once with CLUSTER INFO, reject detected Cluster mode, and never repeat detection during reconnects
  • make reader bucketing connection-independent so owned, legacy, and generic readers register and recover while Redis is offline
  • remove cross-slot fallbacks, Cluster startup/test helpers, and the Cluster-only CI smoke
  • preserve {baseKey}:subKey, timestamps, payloads, standalone TCP/Unix sockets, authentication, and connection pooling

Compatibility

  • removes the low-level RedisConnection::keyslot() method and copy() == -2 result
  • keeps RedisAdapter, RA_Options, ping(key), and time(key) source surfaces otherwise unchanged
  • requires Cluster deployments to migrate their endpoint and data to standalone Redis before upgrading
  • leaves the library and wire-protocol versions unchanged

Validation

  • C++17 Debug and C++20 Release builds
  • 109 compatible tests passed with no failures in each C++17 and C++20 run; two Redis 7.4-only XREAD-tail cases skipped on local Redis 7.0.12
  • ASan/UBSan: 109 passed, two Redis 7.4-only skips, no sanitizer findings
  • TSan: 109 passed, two Redis 7.4-only skips, no race findings
  • proxy coverage for one-time standalone classification, cached Cluster refusal, transport faults, trim failures, server rejection, and READONLY recovery
  • YAML parsing, Python syntax checks, static Cluster-reference audit, and git diff --check

The local Redis 7.0.12 fixture cannot run the existing HEXPIRE watchdog case; the pinned Redis 7.4 CI fixture covers it.

Review requested from @wsulli and @bigsamich.

Closes #65

@derekste
derekste requested a review from a team as a code owner October 7, 2026 16:43
@derekste
derekste requested review from bigsamich and wsulli October 7, 2026 16:43
@bigsamich
bigsamich requested a balanced review from Copilot October 7, 2026 17:37

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Core connection replacement and concurrent reader recovery behavior warrant final human review despite comprehensive tests.

0 open findings

What changed in this PR

Removes Redis Cluster support while preserving standalone Redis compatibility and improving offline reader recovery.

Changes:

  • Replaces Cluster routing with standalone command/reader clients and one-time mode detection.
  • Makes reader registration and recovery connection-independent.
  • Removes Cluster fixtures, CI coverage, and obsolete documentation.
File Description
RedisConnection.hpp Implements standalone clients and Cluster rejection.
RedisAdapter.cpp Simplifies bucketing, copying, and reader recovery.
RedisAdapter.hpp Updates reader and standalone API documentation.
connection_policy_test.cpp Tests cached mode detection.
lifecycle_test.cpp Tests offline reader recovery.
write_failure_test.py Extends proxy classification and reconnect checks.
write_error_test.cpp Adds constructor and Cluster-refusal scenarios.
test.cpp Tests key schema and cross-base utilities.
recovery_test.cpp Removes Cluster recovery coverage.
.github/​workflows/​test.yml Removes Cluster CI smoke test.
scripts/​run-test-redis-cluster.py Deletes private Cluster fixture.
create-cluster Deletes legacy Cluster creation script.
cluster-start.sh Deletes Cluster startup wrapper.
README.md Documents standalone-only support.
docs/​api.md Updates connection and recovery behavior.
docs/​building.md Removes Cluster test instructions.
docs/​stream-subscriptions.md Documents standalone subscription behavior.
docs/​redis-adapter-implementation-spec.md Preserves the braced wire-key schema.
CHANGELOG.md Records Cluster removal and compatibility impact.
.github/​ISSUE_TEMPLATE/​bug.yml Requests supported connection details.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@bigsamich bigsamich left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 95792a3. Looks good. The removal is clean: no Cluster references remain outside the new detection path and docs, reader_token() no longer depends on the connection, and CI (build-test, ASan, TSan) is green. Two minor items and a note:

  1. A cached Cluster refusal still reconnects on every attempt (RedisConnection::connect()). After _initial_server == Unsupported, connect() still builds a pool and sends PING before acceptStandalone() returns false. On a Cluster endpoint, every failed write or read calls reconnect(0). The adapter keeps opening a fresh connection, as often as every ~100 ms, for the life of the process, and only the first attempt logs. Suggest returning false at the top of connect() once the cached result is Unsupported. The cluster-refusal proxy test's ping_probes == 2 would then become 1.

  2. The mode is cached per RedisConnection object, not per endpoint. connect(opts) is public and can target a different host or socket; the new OfflineInitialConnectionDefersModeProbeUntilReachable test does exactly that. The result from the first reachable endpoint then applies to every later one. RedisAdapter always reconnects to _options.cxn, so the adapter is not affected. Either document this on connect() or key the cache on host/port/path.

  3. Note: the PR drops the stop/restart-all-readers block from the reconnect thread. That also closes the "late reconnect thread restarts readers after ~RedisAdapter stopped them" path in #118 (part 2), which may be worth a line in the PR body. #118 stays open for readers restarted from callbacks via removeReader() and setDeferReaders(false).

@derekste

derekste commented Oct 7, 2026

Copy link
Copy Markdown
Member Author

Thanks for the review. I classified both requested changes as non-blocking follow-ups and filed them without changing the approved PR:

The reconnect-thread reader-restart note is now recorded on #118. PR #132 removes that specific restart path, while #118 remains open for the callback-driven shutdown races.

All required checks on this PR are green, and there are no open inline review threads.

@derekste
derekste merged commit 69bf18e into main Oct 7, 2026
4 checks passed
@derekste
derekste deleted the dev/remove-cluster-support branch October 7, 2026 18:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor: eliminate cluster support

3 participants