@@ -1507,8 +1507,36 @@ func (c *ClusterClient) processTxPipeline(ctx context.Context, cmds []Cmder) err
1507
1507
return err
1508
1508
}
1509
1509
1510
- cmdsMap := c .mapCmdsBySlot (cmds )
1510
+ cmdsMap := map [int ][]Cmder {}
1511
+ slot := - 1
1512
+ // split keyed and keyless commands
1513
+ keyedCmds , _ := c .keyedAndKeyessCmds (cmds )
1514
+ if len (keyedCmds ) == 0 {
1515
+ // no keyed commands try random slot
1516
+ slot = hashtag .RandomSlot ()
1517
+ } else {
1518
+ // keyed commands, get slot from them
1519
+ // if more than one slot, return cross slot error
1520
+ cmdsBySlot := c .mapCmdsBySlot (keyedCmds )
1521
+ if len (cmdsBySlot ) > 1 {
1522
+ // cross slot error, we have more than one slot for keyed commands
1523
+ setCmdsErr (cmds , ErrCrossSlot )
1524
+ return ErrCrossSlot
1525
+ }
1526
+ // get the slot, should be only one
1527
+ for sl := range cmdsBySlot {
1528
+ slot = sl
1529
+ break
1530
+ }
1531
+ }
1532
+ // slot was not determined, try random one
1533
+ if slot == - 1 {
1534
+ slot = hashtag .RandomSlot ()
1535
+ }
1536
+ cmdsMap [slot ] = cmds
1537
+
1511
1538
// TxPipeline does not support cross slot transaction.
1539
+ // double check the commands are in the same slot
1512
1540
if len (cmdsMap ) > 1 {
1513
1541
setCmdsErr (cmds , ErrCrossSlot )
1514
1542
return ErrCrossSlot
@@ -1560,6 +1588,18 @@ func (c *ClusterClient) mapCmdsBySlot(cmds []Cmder) map[int][]Cmder {
1560
1588
}
1561
1589
return cmdsMap
1562
1590
}
1591
+ func (c * ClusterClient ) keyedAndKeyessCmds (cmds []Cmder ) ([]Cmder , []Cmder ) {
1592
+ keyedCmds := make ([]Cmder , 0 , len (cmds ))
1593
+ keylessCmds := make ([]Cmder , 0 , len (cmds ))
1594
+ for _ , cmd := range cmds {
1595
+ if cmdFirstKeyPos (cmd ) == 0 {
1596
+ keylessCmds = append (keylessCmds , cmd )
1597
+ } else {
1598
+ keyedCmds = append (keyedCmds , cmd )
1599
+ }
1600
+ }
1601
+ return keyedCmds , keylessCmds
1602
+ }
1563
1603
1564
1604
func (c * ClusterClient ) processTxPipelineNode (
1565
1605
ctx context.Context , node * clusterNode , cmds []Cmder , failedCmds * cmdsMap ,
0 commit comments