@@ -550,8 +550,10 @@ impl RoutingInfo {
550
550
matches ! ( base_routing( cmd) , RouteBy :: AllNodes )
551
551
}
552
552
553
- /// Returns true if the `cmd` is a key-based command.
554
- pub fn is_key_based_cmd ( cmd : & [ u8 ] ) -> bool {
553
+ /// Returns true if the `cmd` is a key-based command that triggers MOVED errors.
554
+ /// A key-based command is one that will be accepted only by the slot owner,
555
+ /// while other nodes will respond with a MOVED error redirecting to the relevant primary owner.
556
+ pub fn is_key_routing_command ( cmd : & [ u8 ] ) -> bool {
555
557
match base_routing ( cmd) {
556
558
RouteBy :: FirstKey
557
559
| RouteBy :: SecondArg
@@ -560,7 +562,18 @@ impl RoutingInfo {
560
562
| RouteBy :: SecondArgSlot
561
563
| RouteBy :: StreamsIndex
562
564
| RouteBy :: MultiShardNoValues
563
- | RouteBy :: MultiShardWithValues => true ,
565
+ | RouteBy :: MultiShardWithValues => {
566
+ if matches ! ( cmd, b"SPUBLISH" ) {
567
+ // SPUBLISH does not return MOVED errors within the slot's shard. This means that even if READONLY wasn't sent to a replica,
568
+ // executing SPUBLISH FOO BAR on that replica will succeed. This behavior differs from true key-based commands,
569
+ // such as SET FOO BAR, where a non-readonly replica would return a MOVED error if READONLY is off.
570
+ // Consequently, SPUBLISH does not meet the requirement of being a command that triggers MOVED errors.
571
+ // TODO: remove this when PRIMARY_PREFERRED route for SPUBLISH is added
572
+ false
573
+ } else {
574
+ true
575
+ }
576
+ }
564
577
RouteBy :: AllNodes | RouteBy :: AllPrimaries | RouteBy :: Random | RouteBy :: Undefined => {
565
578
false
566
579
}
0 commit comments