Skip to content

fix: premature recycles in MGET/MSET helpers#980

Merged
rueian merged 2 commits intomainfrom
fix-helpers-recycle
Apr 8, 2026
Merged

fix: premature recycles in MGET/MSET helpers#980
rueian merged 2 commits intomainfrom
fix-helpers-recycle

Conversation

@rueian
Copy link
Copy Markdown
Collaborator

@rueian rueian commented Apr 7, 2026

Note

Medium Risk
Touches cluster multi-command helpers and command-buffer pooling behavior; incorrect recycling could cause data races or subtle request corruption under concurrency/timeouts.

Overview
Fixes premature recycling of pooled command buffers (mgetcmdsp) used by cluster helpers.

MSet/MDel/MSetNX/JsonMSet now pass the pooled *mgetcmds buffer into doMultiSet, which only returns the buffer to the pool when no response contains a non-Redis error (e.g., context cancellation/deadline). clusterMGet and clusterJsonMGet similarly stop deferring mgetcmdsp.Put and instead return buffers only after successful response processing.

Adds TestClusterHelpersMgetcmdspRecycle to cover recycling behavior across success, Redis-level errors, parse errors, and context-cancellation paths.

Reviewed by Cursor Bugbot for commit 549554d. Bugbot is set up for automated code reviews on this repo. Configure here.

Signed-off-by: Rueian <rueiancsie@gmail.com>
@jit-ci
Copy link
Copy Markdown

jit-ci Bot commented Apr 7, 2026

🛡️ Jit Security Scan Results

CRITICAL HIGH MEDIUM

✅ No security findings were detected in this PR


Security scan by Jit

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes premature recycling of pooled command buffers used by cluster helper functions, to avoid unsafe reuse when DoMulti returns non-Redis errors (e.g., context cancel/deadline) where pipelining internals may still reference the command buffer.

Changes:

  • Refactors doMultiSet to accept the pooled *mgetcmds buffer and only return it to mgetcmdsp when all results have NonRedisError()==nil.
  • Updates clusterMGet and clusterJsonMGet to conditionally return *mgetcmds to the pool based on whether any DoMulti result has a non-Redis error.
  • Adds tests covering success paths, Redis-level errors, and non-Redis errors for the affected helper flows.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
helper.go Adjusts pooling/recycling behavior for cluster helper command buffers to avoid premature reuse on non-Redis errors.
helper_test.go Adds tests exercising cancellation/deadline and error cases for the updated recycling behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread helper.go Outdated
Comment on lines 298 to 306
defer func() {
if recycle {
mgetcmdsp.Put(cmds)
}
}()

for i, resp := range resps {
arr, err := resp.ToArray()
if err != nil {
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

In clusterMGet, if resp.ToArray() returns an error with no NonRedisError (e.g. unexpected reply type / Redis error), the function returns early before reaching the intl.PutCompletedForce(cmds.s[i]) loop. Since these commands are Pin()'d, skipping PutCompletedForce means their CommandSlice buffers won’t be returned to the cmds pool (reducing reuse) even though recycle is still true and it should be safe to recycle them. Consider deferring command recycling when recycle remains true so it also happens on early returns (but still avoid recycling on NonRedisError).

Copilot uses AI. Check for mistakes.
Comment thread helper.go Outdated
Comment on lines 356 to 364
defer func() {
if recycle {
mgetcmdsp.Put(cmds)
}
}()

for i, resp := range resps {
arr, err := resp.ToArray()
if err != nil {
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

Same pattern as clusterMGet: if resp.ToArray() errors without a NonRedisError in clusterJsonMGet, the function returns before the PutCompletedForce loop, so Pin()'d command buffers won’t be recycled even though recycle is true. Consider deferring PutCompletedForce for cmds.s under the same recycle condition so it runs on early returns too (while still skipping recycling on NonRedisError).

Copilot uses AI. Check for mistakes.
Signed-off-by: Rueian <rueiancsie@gmail.com>
@rueian rueian force-pushed the fix-helpers-recycle branch from f29dc4f to 549554d Compare April 8, 2026 05:12
@rueian rueian changed the title fix: premature recycles in helpers fix: premature recycles in MGET/MSET helpers Apr 8, 2026
@rueian rueian merged commit c778f10 into main Apr 8, 2026
55 checks passed
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.

2 participants