@@ -544,16 +544,16 @@ func (c *clusterClient) _pickMulti(multi []Completed) (retries *connretry) {
544
544
545
545
if ! init && c .rslots != nil && c .opt .SendToReplicas != nil {
546
546
for _ , cmd := range multi {
547
- var p conn
547
+ var cc conn
548
548
if c .opt .SendToReplicas (cmd ) {
549
- p = c .rslots [cmd .Slot ()]
549
+ cc = c .rslots [cmd .Slot ()]
550
550
} else {
551
- p = c .pslots [cmd .Slot ()]
551
+ cc = c .pslots [cmd .Slot ()]
552
552
}
553
- if p == nil {
553
+ if cc == nil {
554
554
return nil
555
555
}
556
- count .m [p ]++
556
+ count .m [cc ]++
557
557
}
558
558
559
559
retries = connretryp .Get (len (count .m ), len (count .m ))
@@ -569,7 +569,9 @@ func (c *clusterClient) _pickMulti(multi []Completed) (retries *connretry) {
569
569
} else {
570
570
cc = c .pslots [cmd .Slot ()]
571
571
}
572
-
572
+ if cc == nil { // check cc == nil again in case of non-deterministic SendToReplicas.
573
+ return nil
574
+ }
573
575
re := retries .m [cc ]
574
576
re .commands = append (re .commands , cmd )
575
577
re .cIndexes = append (re .cIndexes , i )
@@ -726,13 +728,22 @@ func (c *clusterClient) DoMulti(ctx context.Context, multi ...Completed) []Redis
726
728
retry:
727
729
retries .RetryDelay = - 1 // Assume no retry. Because client retry flag can be set to false.
728
730
731
+ var cc1 conn
732
+ var re1 * retry
729
733
wg .Add (len (retries .m ))
730
734
mu .Lock ()
735
+ for cc , re := range retries .m {
736
+ delete (retries .m , cc )
737
+ cc1 = cc
738
+ re1 = re
739
+ break
740
+ }
731
741
for cc , re := range retries .m {
732
742
delete (retries .m , cc )
733
743
go c .doretry (ctx , cc , results , retries , re , & mu , & wg , attempts )
734
744
}
735
745
mu .Unlock ()
746
+ c .doretry (ctx , cc1 , results , retries , re1 , & mu , & wg , attempts )
736
747
wg .Wait ()
737
748
738
749
if len (retries .m ) != 0 {
@@ -997,13 +1008,22 @@ func (c *clusterClient) DoMultiCache(ctx context.Context, multi ...CacheableTTL)
997
1008
retry:
998
1009
retries .RetryDelay = - 1 // Assume no retry. Because client retry flag can be set to false.
999
1010
1011
+ var cc1 conn
1012
+ var re1 * retrycache
1000
1013
wg .Add (len (retries .m ))
1001
1014
mu .Lock ()
1015
+ for cc , re := range retries .m {
1016
+ delete (retries .m , cc )
1017
+ cc1 = cc
1018
+ re1 = re
1019
+ break
1020
+ }
1002
1021
for cc , re := range retries .m {
1003
1022
delete (retries .m , cc )
1004
1023
go c .doretrycache (ctx , cc , results , retries , re , & mu , & wg , attempts )
1005
1024
}
1006
1025
mu .Unlock ()
1026
+ c .doretrycache (ctx , cc1 , results , retries , re1 , & mu , & wg , attempts )
1007
1027
wg .Wait ()
1008
1028
1009
1029
if len (retries .m ) != 0 {
0 commit comments