Introduce request & response policy support#4411
Conversation
bd6ee0f to
0fdcacf
Compare
Test Results 308 files + 3 308 suites +3 12m 9s ⏱️ +27s Results for commit 57816a4. ± Comparison against base commit d9b979c. This pull request removes 43 and adds 235 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
There was a problem hiding this comment.
Pull request overview
This PR introduces comprehensive support for Redis cluster request/response policies, enabling intelligent routing of keyless commands and multi-shard operations. The changes implement Redis's command tips specification for cluster deployments.
Changes:
- Added
RequestPolicyandResponsePolicyenums with intelligent routing and aggregation strategies - Implemented keyless command execution with round-robin distribution across cluster nodes
- Added multi-shard command support with automatic key-based slot splitting
- Removed
ClusterCommandArgumentsin favor of unified hash slot tracking inCommandArguments
Reviewed changes
Copilot reviewed 35 out of 35 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| Test files (multiple) | Updated from broadcastCommand() to executeCommand() - proper API migration |
| ClusterReplyAggregatorTest.java | Comprehensive tests for new aggregation utility |
| ClusterCommandExecutorTest.java | Extensive tests for keyless and multi-shard execution |
| ClusterCommandObjectsTest.java | Tests for hash slot grouping logic |
| CommandFlagsRegistryGenerator.java | Extracts request/response policies from Redis command metadata |
| ClusterCommandExecutor.java | Core policy-based routing implementation |
| ClusterReplyAggregator.java | Response aggregation utility (SUM, MIN, MAX, AND, OR, etc.) |
| CommandArguments.java | Added hash slot tracking with caching |
| ClusterCommandObjects.java | Multi-shard command splitting methods |
| RedisClusterClient.java | Multi-shard method overrides (del, mget, mset, etc.) |
| StaticCommandFlagsRegistry*.java | Policy storage and lookup |
| UnifiedJedis.java | Removed broadcast config, deprecated sendCommand methods |
| ClusterCommandArguments.java | Deleted - functionality merged into CommandArguments |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
I still need to review the read-only connection intent in more detail, but here are my findings so far:
- The main question, in my view, is currently missing support for the default behavior for commands that do not specify a request_policy hint.
- I would suggest separating the deprecation of sendCommand into a dedicated PR and targeting it for merge in 7.x.
- Regarding exposing a broadcast API at the RedisClient level: I understand this as sending the same command to multiple nodes. The result could either:
- Be returned as raw replies from all contacted endpoints (List<Reply>), or
- Be returned as a single aggregated Reply.
- In the latter case, it would likely make sense to make the aggregation strategy configurable (e.g., by injecting an aggregator/collector responsible for processing the results).
- We should also consider implementing retry, redirect handling, and read replay logic in a shared/common layer. This would help ensure consistent behavior across different scenarios (keyed and keyless commands).
src/test/java/redis/clients/jedis/codegen/CommandFlagsRegistryGenerator.java
Outdated
Show resolved
Hide resolved
src/test/java/redis/clients/jedis/codegen/CommandFlagsRegistryGenerator.java
Outdated
Show resolved
Hide resolved
src/test/java/redis/clients/jedis/codegen/CommandFlagsRegistryGenerator.java
Show resolved
Hide resolved
src/test/java/redis/clients/jedis/codegen/CommandFlagsRegistryGenerator.java
Outdated
Show resolved
Hide resolved
src/test/java/redis/clients/jedis/codegen/CommandFlagsRegistryGenerator.java
Outdated
Show resolved
Hide resolved
src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java
Outdated
Show resolved
Hide resolved
src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java
Outdated
Show resolved
Hide resolved
src/main/java/redis/clients/jedis/executors/ClusterReplyAggregator.java
Outdated
Show resolved
Hide resolved
6bfffe6 to
d757662
Compare
🛡️ Jit Security Scan Results✅ No security findings were detected in this PR
Security scan by Jit
|
src/main/java/redis/clients/jedis/executors/ClusterReplyAggregator.java
Outdated
Show resolved
Hide resolved
src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java
Outdated
Show resolved
Hide resolved
src/main/java/redis/clients/jedis/providers/ClusterConnectionProvider.java
Show resolved
Hide resolved
src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java
Outdated
Show resolved
Hide resolved
src/main/java/redis/clients/jedis/StaticCommandFlagsRegistryInitializer.java
Outdated
Show resolved
Hide resolved
…cCommandFlagsRegistry
…tor interface The logic on how command should be routed should be decided in CommandExecutor based on command request/response policy and client configuration
src/main/java/redis/clients/jedis/executors/ClusterReplyAggregator.java
Outdated
Show resolved
Hide resolved
src/main/java/redis/clients/jedis/executors/ClusterReplyAggregator.java
Outdated
Show resolved
Hide resolved
src/main/java/redis/clients/jedis/StaticCommandFlagsRegistryInitializer.java
Show resolved
Hide resolved
…rt' into im/request-response-policy-support
src/main/java/redis/clients/jedis/executors/ClusterReplyAggregator.java
Outdated
Show resolved
Hide resolved
|
run integration tests |
|
src/main/java/redis/clients/jedis/executors/ClusterReplyAggregator.java
Outdated
Show resolved
Hide resolved
src/main/java/redis/clients/jedis/executors/ClusterReplyAggregator.java
Outdated
Show resolved
Hide resolved
src/main/java/redis/clients/jedis/executors/ClusterReplyAggregator.java
Outdated
Show resolved
Hide resolved
…est policy in Cluster Pipeline (#4466) * reject commands with ALL_NODES,ALL_SHARDS,MULTI_SHARD request policy in cluster pipeline * run test on topic branches * api docs fix * If the command has keys that route to a single slot, allow it
* refactore: fix empty Map/Set should return emtpy not null refactore: statefull aggregators fix tests refactore: statefull aggregators * refactore: statefull aggregators add test for ReplyAggregatorTest * refactore: MultiNodeResultAggregator to aggregator package and mark with @internal * refactore: reuse LogicalAnd & LogicalOr aggregators * format * remove ClusterReplyAggregator replaced by aggregators/ClusterReplyAggregator * triger test * address review comments and fix Set[byte[]] aggregation * address review comments - test puts entries into wrong map variable - Byte array set dedup skipped when first part empty * address review comments - JedisByteHashMapAggregator.add() and JedisByteMapAggregator.add() skip empty maps * format * parameterize map test * remove unused import
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

This PR introduces support for request/response policies in Redis cluster command execution, enabling proper handling of keyless commands and multi-shard operations. The changes implement Redis's command tips specification for cluster deployments, allowing the Jedis client to intelligently route commands to appropriate nodes and aggregate responses based on command-specific policies.
Fixes: #990
Note
High Risk
High risk because it rewires Redis Cluster command routing/execution (including keyless and broadcast behaviors), adds response aggregation logic, and changes how hash slots are tracked for pipeline/node selection.
Overview
Adds Redis Cluster command tip support by extending
CommandFlagsRegistrywithRequestPolicy/ResponsePolicyand updating the static registry generator output to include these policies.Reworks cluster execution to route commands by policy in
ClusterCommandExecutor(keyless commands use round-robin connections,ALL_SHARDS/ALL_NODESare broadcast with aggregated replies, and new multi-shard execution aggregates per-slot sub-commands), introducing new connection resolvers and reply aggregators plus clearer multi-node error reporting (JedisClusterOperationExceptionnow carries node info; new aggregation exceptions).Introduces multi-shard implementations for cross-slot commands by splitting arguments by hash slot in
ClusterCommandObjectsand overridingRedisClusterClientmethods likedel/exists/mget/mset/unlink/touch/msetexto transparently execute across shards while preserving input order.Refactors key tracking by removing
ClusterCommandArgumentsand makingCommandArgumentsrecord keys + cached hash slots (addHashSlotKey(s)), updates pipeline routing/validation to reject commands that can’t be routed to a single slot, and removes the old broadcast/round-robin config path fromUnifiedJedis. Also expands CI branch triggers (topic/**) and updatespom.xmlinclude patterns for coverage/validation.Written by Cursor Bugbot for commit 3d286f8. This will update automatically on new commits. Configure here.