Fixes #1386; pipeline.Exec() sometimes returns spurious `StatusCmd`

This is caused by function `wrapMultiExec` sometimes clobbering the caller's
cmd slice, corrupting future requests.
This commit is contained in:
Scott Parkerson 2020-09-17 10:35:34 -04:00
parent 2eb40d83aa
commit 26a6d4714c
2 changed files with 22 additions and 5 deletions

View File

@ -1,6 +1,8 @@
package redis_test package redis_test
import ( import (
"strconv"
"github.com/go-redis/redis/v8" "github.com/go-redis/redis/v8"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
@ -67,6 +69,21 @@ var _ = Describe("pipelining", func() {
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(cmds).To(HaveLen(1)) Expect(cmds).To(HaveLen(1))
}) })
It("handles large pipelines", func() {
for callCount := 1; callCount < 16; callCount++ {
for i := 1; i <= callCount; i++ {
pipe.SetNX(ctx, strconv.Itoa(i)+"_key", strconv.Itoa(i)+"_value", 0)
}
cmds, err := pipe.Exec(ctx)
Expect(err).NotTo(HaveOccurred())
Expect(cmds).To(HaveLen(callCount))
for _, cmd := range cmds {
Expect(cmd).To(BeAssignableToTypeOf(&redis.BoolCmd{}))
}
}
})
} }
Describe("Pipeline", func() { Describe("Pipeline", func() {

View File

@ -492,11 +492,11 @@ func wrapMultiExec(ctx context.Context, cmds []Cmder) []Cmder {
if len(cmds) == 0 { if len(cmds) == 0 {
panic("not reached") panic("not reached")
} }
cmds = append(cmds, make([]Cmder, 2)...) cmdCopy := make([]Cmder, len(cmds)+2)
copy(cmds[1:], cmds[:len(cmds)-2]) cmdCopy[0] = NewStatusCmd(ctx, "multi")
cmds[0] = NewStatusCmd(ctx, "multi") copy(cmdCopy[1:], cmds)
cmds[len(cmds)-1] = NewSliceCmd(ctx, "exec") cmdCopy[len(cmdCopy)-1] = NewSliceCmd(ctx, "exec")
return cmds return cmdCopy
} }
func txPipelineReadQueued(rd *proto.Reader, statusCmd *StatusCmd, cmds []Cmder) error { func txPipelineReadQueued(rd *proto.Reader, statusCmd *StatusCmd, cmds []Cmder) error {