@@ -550,8 +550,10 @@ impl RoutingInfo {
550550 matches ! ( base_routing( cmd) , RouteBy :: AllNodes )
551551 }
552552
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 {
555557 match base_routing ( cmd) {
556558 RouteBy :: FirstKey
557559 | RouteBy :: SecondArg
@@ -560,7 +562,18 @@ impl RoutingInfo {
560562 | RouteBy :: SecondArgSlot
561563 | RouteBy :: StreamsIndex
562564 | 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+ }
564577 RouteBy :: AllNodes | RouteBy :: AllPrimaries | RouteBy :: Random | RouteBy :: Undefined => {
565578 false
566579 }
0 commit comments