Fix CROSSSLOT in lock renewal for useSingleServer() behind a cluster proxy#7114
Open
govansmailbox wants to merge 1 commit into
Open
Conversation
govansmailbox
force-pushed
the
fix/single-connection-manager-calc-slot-cluster-detected
branch
from
May 7, 2026 10:24
2d9ad82 to
5602659
Compare
…proxy When Redisson is configured with useSingleServer() pointing at a proxy that fronts a Redis Cluster, the existing cluster-detection mechanism (874588f) correctly sets clusterDetected=true via a Lua CROSSSLOT probe. However, once detected, the lock renewal path (RenewalTask) switches to the cluster branch and groups locks by slot using calcSlot(). The problem: SingleConnectionManager never overrode calcSlot(), so it fell through to MasterSlaveConnectionManager which always returned singleSlotRange.getStartSlot() (effectively 0). This collapsed every lock key into slot 0, causing the renewal to send one Lua script containing all lock keys to the proxy. The proxy routed it to one backend node which saw keys from multiple real cluster slots and threw CROSSSLOT -- the same error the detection was meant to prevent. Fix: - Override calcSlot(String), calcSlot(byte[]) and calcSlot(ByteBuf) in SingleConnectionManager to compute real Redis cluster CRC16 hash-slot values (including hash-tag extraction) when clusterSetup is detected. In non-cluster single-server mode the existing behaviour (slot 0) is preserved. - Extract the shared CRC16 + hash-tag slot-calculation logic into a new package-private helper SlotCalculator so that both ClusterConnectionManager and SingleConnectionManager use one canonical implementation with no duplication. Tests: - Added SlotCalculatorTest covering: null safety, plain keys, hash-tag extraction, invalid/edge-case tags (empty {}, unclosed brace), multiple brace pairs (first tag wins), cross-overload consistency (String / byte[] / ByteBuf produce identical slots), slot range validity [0,16384) and ByteBuf non-destructive read (readerIndex unchanged). All 29 tests pass. Fixes: redisson#7017 Signed-off-by: Elangovan G <govansmailbox@gmail.com> Signed-off-by: Elangovan G <eg@egP9M7G.omnissa.com>
govansmailbox
force-pushed
the
fix/single-connection-manager-calc-slot-cluster-detected
branch
from
May 7, 2026 10:51
5602659 to
795c97f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When Redisson is configured with useSingleServer() pointing at a proxy that fronts a Redis Cluster, the existing cluster-detection mechanism (874588f) correctly sets clusterDetected=true via a Lua CROSSSLOT probe.
However, once detected, the lock renewal path (RenewalTask) switches to the cluster branch and groups locks by slot using calcSlot(). The problem: SingleConnectionManager never overrode calcSlot(), so it fell through to MasterSlaveConnectionManager which always returned singleSlotRange.getStartSlot() (effectively 0). This collapsed every lock key into slot 0, causing the renewal to send one Lua script containing all lock keys to the proxy. The proxy routed it to one backend node which saw keys from multiple real cluster slots and threw CROSSSLOT -- the same error the detection was meant to prevent.
Fix:
Tests:
Fixes: #7116