Skip to main content

Route

Enum Route 

Source
pub enum Route {
Show 38 variants Local, Single(usize), DelKeys, ExistsKeys, Dbsize, Flush, Save, BgSave, RewriteAof, MSet, Gather(MultiOp), ZAlgebraStore(ZCombine), GeoStore { src: Vec<u8>, dst: Vec<u8>, }, FeedRead, FeedTail, FeedShards, PrefixStats, ClientList, ClientKill, Extension, ReplWait { numreplicas: u32, timeout_ms: u64, }, ReplToken, ReplBarrier { offsets: Vec<u64>, timeout_ms: u64, miss: Vec<u8>, }, Keys(Option<Vec<u8>>), Scan(Result<ScanArgs, &'static str>), RandomKey, Subscribe, Unsubscribe, Psubscribe, Punsubscribe, Publish, Watch, Unwatch, Hello, Rename { nx: bool, }, ListMove { from_left: bool, to_left: bool, }, Slowlog(SlowlogSub), XReadGather { streams: Vec<(Vec<u8>, Vec<u8>)>, count: Option<usize>, group: Option<XGroupCtx>, },
}
Expand description

How a command maps onto shards.

Variants§

§

Local

Keyless; execute on the connection’s own shard (e.g. PING).

§

Single(usize)

Single-key; route by args[idx].

§

DelKeys

args[1..] are keys; delete each on its shard, sum the counts.

§

ExistsKeys

args[1..] are keys; count existing across shards.

§

Dbsize

Sum every shard’s key count.

§

Flush

Flush every shard.

§

Save

Snapshot every shard’s store to disk, synchronously (SAVE — blocks until durable, the Redis contract for the explicit form).

§

BgSave

BGSAVE — collect a COW view per shard and persist in the background; the command returns once the views are frozen.

§

RewriteAof

BGREWRITEAOF — rebuild every shard’s AOF from in-memory state. Each shard freezes a COW view and hands the dump to its persist worker, so the reply returns before the rewrite is durable.

§

MSet

MSETargs[1..] are key/value pairs, routed per key’s shard.

§

Gather(MultiOp)

Cross-shard multi-key gather (MGET / SINTER / SUNION / SDIFF / ZINTERCARD): each key’s payload is fetched on its owning shard and the origin reduces them per crate::MultiOp.

§

ZAlgebraStore(ZCombine)

zset/set algebra *STORE family: gather sources, combine per crate::message::ZCombine, materialize at args[1].

§

GeoStore

Geo *STORE family — GEOSEARCHSTORE dst src … and GEORADIUS[BYMEMBER] src … STORE|STOREDIST dst.

These MUST be routed, not left to the catch-all Route::Single(1): GEOSEARCHSTORE puts the DESTINATION at argv[1] (so the search then read the source off the wrong shard — :0, or “could not decode requested zset member” for FROMMEMBER) while GEORADIUS puts the SOURCE there (so the destination was written into the source’s shard, invisible to every later read of it). Both keys are carried here because neither sits at a fixed argv index — the legacy forms hide dst behind an option-soup scan.

The search runs on src’s shard (crate::Commands::geo_search), the write lands on dst’s (Op::ZStoreResult) — see [crate::exec_geostore].

Fields

§src: Vec<u8>
§dst: Vec<u8>
§

FeedRead

FEED.READ <shard> <gen> <offset> … — shard-index routed.

§

FeedTail

FEED.TAIL <shard>.

§

FeedShards

FEED.SHARDS — answered locally.

§

PrefixStats

PREFIX.STATS <prefix> — all-shard fanout, summed.

§

ClientList

CLIENT LIST — all-shard fanout; each shard renders its conn table rows, the origin concatenates into one bulk reply.

§

ClientKill

CLIENT KILL … — all-shard fanout; each shard closes its matching conns, the origin sums (or maps the legacy positional form to +OK / -ERR).

§

Extension

Extension fan-out (IDX.* reads): every shard runs Commands::extension_op, the origin reduces.

§

ReplWait

WAIT numreplicas timeout — all-shard barrier: each shard answers (possibly deferred until its replicas ACK or the deadline) with how many of its replicas acked its master_repl_offset at arm time; the origin replies the MIN. timeout_ms == 0 = the Redis “wait forever” form (the runtime hard-caps it — see exec_replwait::WAIT_HARD_CAP_MS).

Fields

§numreplicas: u32
§timeout_ms: u64
§

ReplToken

REPL.TOKEN on a primary — gather every shard’s (feed generation, next_offset) pair into one flat array.

§

ReplBarrier

REPL.WAIT on a replica — all-shard applied barrier: shard i answers once its replication-apply position reaches offsets[i] (or the deadline passes). All met → +OK; any timeout → the pre-built miss reply (kevy sends -MISDIRECTED writer is <primary>). The command layer builds miss because the upstream address is its knowledge, not the runtime’s.

Fields

§offsets: Vec<u64>
§timeout_ms: u64
§miss: Vec<u8>
§

Keys(Option<Vec<u8>>)

KEYS pattern — every shard returns its matching keys.

§

Scan(Result<ScanArgs, &'static str>)

SCAN cursor [MATCH pattern] [COUNT count] [TYPE type] — a real cursor iterator: each call visits ~COUNT buckets of ONE shard (chaining into the next shard only while the work budget lasts) and replies [next-cursor, keys]. Err carries the pre-parsed error message the command layer wants on the wire (invalid cursor / syntax error) — the runtime replies it verbatim.

§

RandomKey

RANDOMKEY — one arbitrary key across all shards.

§

Subscribe

SUBSCRIBE / UNSUBSCRIBE — connection-level (modifies this conn).

§

Unsubscribe

§

Psubscribe

PSUBSCRIBE pattern [pattern ...] / PUNSUBSCRIBE [pattern ...] — like Subscribe/Unsubscribe but the conn registers Redis-glob patterns; PUBLISH to a matching channel delivers a pmessage frame. Connection-level (modifies this conn + shared pattern registry).

§

Punsubscribe

§

Publish

PUBLISH channel message — delivered to subscribers on every core.

§

Watch

WATCH key [key ...] — fan-out to record per-shard versions, then stash the (key, version) pairs in the conn’s watched set so the next EXEC can validate them. Connection-level.

§

Unwatch

UNWATCH — clear the conn’s watched set. Connection-level, local.

§

Hello

HELLO [protover [AUTH user pass] [SETNAME name]] — server handshake; on HELLO 3 flips the conn into RESP3 mode (per-conn proto field). Reply shape itself is proto-aware (V2: array of pairs; V3: Map). Connection-level, dispatch via the crate::Commands::hello_reply hook so embedders set their own server metadata.

§

Rename

RENAME source destination / RENAMENX source destination. The runtime handles the two-shard decision: same-shard renames go through one atomic crate::Store::rename on the owning shard; cross- shard renames use the Take→Put orchestrator (lands in v2-3b; v2-3a emits -CROSSSHARD ... for that case).

Fields

§nx: bool

true for RENAMENX (no overwrite — reply :0 if dst exists).

§

ListMove

RPOPLPUSH src dst / LMOVE src dst LEFT|RIGHT LEFT|RIGHT / BRPOPLPUSH src dst timeout, once the blocking form has an element to serve.

These MUST be routed, not left to Route::Single(1). The source and the destination are different keys and can live on different shards; the catch-all route hashes args[1] (the source), so the destination push executed on the SOURCE’s shard and the element was written into a keyspace nobody would ever read it from. It returned the moved value, so the caller believed it had worked. Measured on an 8-shard server: 11 of 12 moves silently lost the element.

Same-shard pairs are one atomic Op on the owning shard. Cross-shard pairs run the Take→Push orchestrator (mirroring Self::Rename), which is NOT atomic — see exec_listmove.

Fields

§from_left: bool

Pop from the head of the source (LMOVE ... LEFT ...) rather than the tail (RPOPLPUSH).

§to_left: bool

Push onto the head of the destination (RPOPLPUSH, LMOVE ... LEFT) rather than the tail.

§

Slowlog(SlowlogSub)

SLOWLOG GET / LEN / RESET / HELP. The sub-command + parsed args are pre-decoded at routing time so the runtime knows whether to short-circuit (HELP / error) or fan out across shards (GET / LEN / RESET). See crate::parse_slowlog_sub.

§

XReadGather

Non-blocking XREAD / XREADGROUP over multiple streams — fan each stream out to its owning shard and merge the per-stream replies in request order (single-stream forms still route via Self::Single). Each element is (stream key, last-seen id); count is the optional COUNT cap applied per stream; group Some makes each per-shard sub-query an XREADGROUP (a write — PEL / last-delivered updates happen on each stream’s owning shard and are AOF-logged there as the rewritten single-stream command). The command set builds this only for the non-blocking, ≥2-stream forms; blocking reads park on the origin shard instead (see the cross-shard BLOCK arbiter).

Fields

§streams: Vec<(Vec<u8>, Vec<u8>)>
§count: Option<usize>

Trait Implementations§

Source§

impl Debug for Route

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for Route

Source§

fn eq(&self, other: &Route) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Route

Auto Trait Implementations§

§

impl Freeze for Route

§

impl RefUnwindSafe for Route

§

impl Send for Route

§

impl Sync for Route

§

impl Unpin for Route

§

impl UnsafeUnpin for Route

§

impl UnwindSafe for Route

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.