Use simplified key specs in cluster slot verification#1640
Use simplified key specs in cluster slot verification#1640
Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors cluster slot verification to rely on the existing simplified key-spec resolution path (via SimpleRespKeySpec + TryGetKeySearchArgsFromSimpleKeySpec) instead of maintaining a separate “precomputed first/last/step” extraction implementation.
Changes:
- Replaces
ClusterSlotVerificationInput’s precomputed index fields withSimpleRespKeySpec[] keySpecsplus anisSubCommandflag. - Updates multi-key slot verification to iterate over all key specs and resolve key positions per-spec via
TryGetKeySearchArgsFromSimpleKeySpec. - Removes
ExtractKeySpecsfromIClusterProviderand deletes its implementation; updates call sites to useTryGetSimpleRespCommandInfo.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| libs/server/SessionParseStateExtensions.cs | Exposes TryGetKeySearchArgsFromSimpleKeySpec publicly for reuse across projects. |
| libs/server/Resp/RespServerSessionSlotVerify.cs | Switches slot verification setup to SimpleRespCommandInfo key specs and sets isSubCommand (incl. BITOP special-case). |
| libs/server/Cluster/IClusterProvider.cs | Removes ExtractKeySpecs from the provider interface. |
| libs/server/Cluster/ClusterSlotVerificationInput.cs | Replaces index/step fields with keySpecs + isSubCommand. |
| libs/cluster/Session/SlotVerification/ClusterSlotVerify.cs | Reworks multi-key slot verification to resolve/verify keys per key spec. |
| libs/cluster/Session/ClusterSession.cs | Uses TryGetSimpleRespCommandInfo and keySpecs for cluster subcommand slot verification. |
| libs/cluster/Server/ClusterProvider.cs | Deletes now-unused ExtractKeySpecs implementation. |
Comments suppressed due to low confidence (1)
libs/server/SessionParseStateExtensions.cs:933
TryGetKeySearchArgsFromSimpleKeySpeccan read outside theSessionParseStatebuffer in Release builds. In the keyword-search branch it usesstep = -1whenkeySpec.BeginSearch.Index < 0, but the loop condition isi < parseState.Count, soiwill eventually become negative andGetArgSliceByRef(i)will dereference beforebufferPtr(e.g.,MIGRATEhas aBeginSearchKeywordspec withStartFrom: -2inlibs/resources/RespCommandsInfo.json). Also, key-num/range cases rely onDebug.Assertfor bounds (keyNumIdx,lastKeyIdx), which doesn’t protect Release builds and can lead to OOB access viaTryGetInt/GetArgSliceByRef.
Please add runtime bounds checks and return false for invalid/missing args: use a backward-scan condition (i >= 0) when scanning with step < 0, validate i + 1 < parseState.Count when a keyword is found, validate keyNumIdx is in-range and TryGetInt succeeds, and ensure computed firstIdx/lastIdx stay within [0, parseState.Count - 1].
public static bool TryGetKeySearchArgsFromSimpleKeySpec(this ref SessionParseState parseState, SimpleRespKeySpec keySpec, bool isSubCommand, out (int firstIdx, int lastIdx, int step) searchArgs)
{
searchArgs = (-1, -1, -1);
// Determine the starting index for searching keys
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <[email protected]>
Problem:
ClusterSlotVerificationInputcurrently stores pre-computed key search fields (firstKey,lastKey,step,keyNumOffset) populated byClusterProvider.ExtractKeySpecs- this logic may ignore some scenarios such as multiple key specifications per command.ExtractKeySpecsduplicated key spec resolution logic that already existed inTryGetKeySearchArgsFromSimpleKeySpec, with its own implementation handling multiple key spec types (BeginSearchIndex,FindKeysRange,FindKeysKeyNum).keyNumOffsetfield was a workaround for 2-spec commands where a count argument sits between keys —TryGetKeySearchArgsFromSimpleKeySpechandles this naturally by resolving each spec independentlyChanges:
ClusterSlotVerificationInput— ReplacedfirstKey,lastKey,step,keyNumOffsetwithSimpleRespKeySpec[] keySpecsandbool isSubCommandMultiKeySlotVerify— Now iterates over keySpecs, resolves each viaTryGetKeySearchArgsFromSimpleKeySpec, and verifies keys per-spec; eliminateskeyNumOffsetskip hackCanServeSlot— UsesTryGetSimpleRespCommandInfoinstead ofTryFastGetRespCommandInfo+ExtractKeySpecsClusterSession.ProcessClusterCommands— Same pattern change; removed unusedcommandInfovariableClusterProvider.ExtractKeySpecs— Deleted entirely (65 lines)IClusterProvider— Removed ExtractKeySpecs from interfaceTryGetKeySearchArgsFromSimpleKeySpec— Changed from internal to public for cross-project accessResult: