Skip to content

Commit 9043b26

Browse files
skif48rueian
andcommitted
fix redirections that happen for cmds with InitSlot
* fix redirections that happen for cmds with InitSlot Signed-off-by: vladyslavusenko <[email protected]> * avoid ad-hoc connection assignments on moved redirections for keyless commands Signed-off-by: vladyslavusenko <[email protected]> * add test for MOVED redirection received for EXEC command Signed-off-by: vladyslavusenko <[email protected]> * add test for MOVED redirection received for EXEC command Signed-off-by: Rueian <[email protected]> --------- Signed-off-by: vladyslavusenko <[email protected]> Signed-off-by: Rueian <[email protected]> Co-authored-by: Rueian <[email protected]> Signed-off-by: Rueian <[email protected]>
1 parent f05dbeb commit 9043b26

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

cluster.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ func (c *clusterClient) redirectOrNew(addr string, prev conn, slot uint16, mode
502502
p := c.connFn(addr, c.opt)
503503
cc = connrole{conn: p}
504504
c.conns[addr] = cc
505-
if mode == RedirectMove {
505+
if mode == RedirectMove && slot != cmds.InitSlot {
506506
c.wslots[slot] = p
507507
}
508508
} else if prev == cc.conn {
@@ -516,7 +516,7 @@ func (c *clusterClient) redirectOrNew(addr string, prev conn, slot uint16, mode
516516
p := c.connFn(addr, c.opt)
517517
cc = connrole{conn: p}
518518
c.conns[addr] = cc
519-
if mode == RedirectMove { // MOVED should always point to the primary.
519+
if mode == RedirectMove && slot != cmds.InitSlot { // MOVED should always point to the primary.
520520
c.wslots[slot] = p
521521
}
522522
}

cluster_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6503,6 +6503,54 @@ func TestClusterClientMovedRetry(t *testing.T) {
65036503
}
65046504
})
65056505

6506+
t.Run("DoMulti Retry on MOVED for EXEC", func(t *testing.T) {
6507+
client, m := setup()
6508+
6509+
attempts := 0
6510+
m.DoMultiFn = func(multi ...Completed) *redisresults {
6511+
attempts++
6512+
6513+
results := make([]RedisResult, len(multi))
6514+
for i, cmd := range multi {
6515+
cmdName := cmd.Commands()[0]
6516+
if cmdName == "MULTI" {
6517+
results[i] = newResult(strmsg('+', "OK"), nil)
6518+
} else if cmdName == "EXEC" {
6519+
if attempts == 1 {
6520+
// return MOVED error only for EXEC on first attempt
6521+
// making sure we do not panic on wslots connection reassignment because EXEC's "slot" is 16384 (InitSlot)
6522+
results[i] = newResult(strmsg('-', "MOVED 1 127.0.0.1"), nil)
6523+
} else {
6524+
// return a successful transaction result for the retry
6525+
results[i] = newResult(slicemsg('*', []RedisMessage{strmsg('+', "some_value")}), nil)
6526+
}
6527+
} else {
6528+
results[i] = newResult(strmsg('+', "QUEUED"), nil)
6529+
}
6530+
}
6531+
return &redisresults{s: results}
6532+
}
6533+
6534+
cmds := []Completed{
6535+
client.B().Multi().Build(),
6536+
client.B().Get().Key("some_key").Build(),
6537+
client.B().Exec().Build(),
6538+
}
6539+
resps := client.DoMulti(context.Background(), cmds...)
6540+
6541+
if attempts != 2 {
6542+
t.Fatalf("expected 2 attempts, got %d", attempts)
6543+
}
6544+
6545+
if len(resps) != 3 {
6546+
t.Fatalf("unexpected response length %v", len(resps))
6547+
}
6548+
6549+
if vs, err := resps[2].AsStrSlice(); err != nil || vs[0] != "some_value" {
6550+
t.Fatalf("unexpected response %v %v", vs, err)
6551+
}
6552+
})
6553+
65066554
t.Run("DoMulti Retry on ASK", func(t *testing.T) {
65076555
client, m := setup()
65086556

0 commit comments

Comments
 (0)