@@ -555,35 +555,54 @@ func (c *clusterClient) _pickMulti(multi []Completed) (retries *connretry, last
555
555
return retries , last , toReplica
556
556
}
557
557
558
+ inits := 0
558
559
for _ , cmd := range multi {
559
560
if cmd .Slot () == cmds .InitSlot {
561
+ inits ++
560
562
continue
561
563
}
564
+ if last == cmds .InitSlot {
565
+ last = cmd .Slot ()
566
+ } else if init && last != cmd .Slot () {
567
+ panic (panicMixCxSlot )
568
+ }
562
569
p := c .pslots [cmd .Slot ()]
563
570
if p == nil {
564
571
return nil , 0 , false
565
572
}
566
573
count .m [p ]++
567
574
}
568
575
576
+ if last == cmds .InitSlot {
577
+ // if all commands have no slots, such as INFO, we pick a non-nil slot.
578
+ for i , p := range c .pslots {
579
+ if p != nil {
580
+ last = uint16 (i )
581
+ count .m [p ] = inits
582
+ break
583
+ }
584
+ }
585
+ if last == cmds .InitSlot {
586
+ return nil , 0 , false
587
+ }
588
+ }
589
+
569
590
retries = connretryp .Get (len (count .m ), len (count .m ))
570
591
for cc , n := range count .m {
571
592
retries .m [cc ] = retryp .Get (0 , n )
572
593
}
573
594
conncountp .Put (count )
574
595
575
596
for i , cmd := range multi {
597
+ var cc conn
576
598
if cmd .Slot () != cmds .InitSlot {
577
- if last == cmds .InitSlot {
578
- last = cmd .Slot ()
579
- } else if init && last != cmd .Slot () {
580
- panic (panicMixCxSlot )
581
- }
582
- cc := c .pslots [cmd .Slot ()]
583
- re := retries .m [cc ]
584
- re .commands = append (re .commands , cmd )
585
- re .cIndexes = append (re .cIndexes , i )
599
+ cc = c .pslots [cmd .Slot ()]
600
+ } else {
601
+ cc = c .pslots [last ]
586
602
}
603
+ re := retries .m [cc ]
604
+ re .commands = append (re .commands , cmd )
605
+ re .cIndexes = append (re .cIndexes , i )
587
606
}
588
607
return retries , last , false
589
608
}
@@ -669,19 +688,12 @@ func (c *clusterClient) DoMulti(ctx context.Context, multi ...Completed) []Redis
669
688
return nil
670
689
}
671
690
672
- retries , slot , toReplica , err := c .pickMulti (ctx , multi )
691
+ retries , _ , _ , err := c .pickMulti (ctx , multi )
673
692
if err != nil {
674
693
return fillErrs (len (multi ), err )
675
694
}
676
695
defer connretryp .Put (retries )
677
696
678
- if len (retries .m ) <= 1 {
679
- for _ , re := range retries .m {
680
- retryp .Put (re )
681
- }
682
- return c .doMulti (ctx , slot , multi , toReplica )
683
- }
684
-
685
697
var wg sync.WaitGroup
686
698
var mu sync.Mutex
687
699
@@ -730,44 +742,6 @@ func fillErrs(n int, err error) (results []RedisResult) {
730
742
return results
731
743
}
732
744
733
- func (c * clusterClient ) doMulti (ctx context.Context , slot uint16 , multi []Completed , toReplica bool ) []RedisResult {
734
- attempts := 1
735
-
736
- retry:
737
- cc , err := c .pick (ctx , slot , toReplica )
738
- if err != nil {
739
- return fillErrs (len (multi ), err )
740
- }
741
- resps := cc .DoMulti (ctx , multi ... )
742
- process:
743
- for i , resp := range resps .s {
744
- switch addr , mode := c .shouldRefreshRetry (resp .Error (), ctx ); mode {
745
- case RedirectMove :
746
- if c .retry && allReadOnly (multi ) {
747
- resultsp .Put (resps )
748
- resps = c .redirectOrNew (addr , cc , multi [i ].Slot (), mode ).DoMulti (ctx , multi ... )
749
- goto process
750
- }
751
- case RedirectAsk :
752
- if c .retry && allReadOnly (multi ) {
753
- resultsp .Put (resps )
754
- resps = askingMulti (c .redirectOrNew (addr , cc , multi [i ].Slot (), mode ), ctx , multi )
755
- goto process
756
- }
757
- case RedirectRetry :
758
- if c .retry && allReadOnly (multi ) {
759
- shouldRetry := c .retryHandler .WaitOrSkipRetry (ctx , attempts , multi [i ], resp .Error ())
760
- if shouldRetry {
761
- resultsp .Put (resps )
762
- attempts ++
763
- goto retry
764
- }
765
- }
766
- }
767
- }
768
- return resps .s
769
- }
770
-
771
745
func (c * clusterClient ) doCache (ctx context.Context , cmd Cacheable , ttl time.Duration ) (resp RedisResult ) {
772
746
attempts := 1
773
747
0 commit comments