Skip to main content

Module dispatch

Module dispatch 

Source
Expand description

From a decoded command to a written reply.

This is the layer Y23 exists to keep thin. The wire and the embedded API both have to reach the same code, or there are two implementations of INCR and one of them is wrong. So yo-kv holds one method per command taking ordinary Rust values, and everything here is about the part that is only true on a socket: which keyword goes where, which combinations a real server refuses, and which of the two protocols the answer is spelled in.

§What runs a command

Server holds the databases. Session holds what one connection has chosen: which database, which name it gave itself, what its id is. The protocol version lives in the Out because that is what needs it, and HELLO changes it there.

use yo_resp::{Argv, Limits, Out, Proto};
use yo_resp::dispatch::{Args, Flow, Server, Session, execute};

let mut server = Server::new();
let mut session = Session::new(1);
let mut out = Out::new(Proto::Resp2);

let wire = b"*3\r\n$3\r\nSET\r\n$1\r\nk\r\n$1\r\nv\r\n";
let mut argv = Argv::new();
argv.decode(wire, &Limits::default())?;
let flow = execute(&mut server, &mut session, Args::new(&argv, wire), &mut out);

assert_eq!(flow, Flow::Continue);
assert_eq!(out.as_slice(), b"+OK\r\n");

§Errors are values until the last moment

A command body returns a Result, and this module turns the error into the line that goes on the wire. That is what keeps the same body usable from the embedded API, where an error is a value with a Code on it and not a sentence to be parsed.

The reply buffer is rolled back to where it was before a failing command wrote anything, so a body that checks its arguments halfway through cannot leave half a reply in front of the error.

§Nothing here allocates

Arguments are slices of the connection’s read buffer, keywords are compared in place, numbers are written straight into the reply, and the pairs of MSET reach the store as an iterator rather than a Vec. The two places that do allocate, an error message and the text of INFO, say so and wrap it, because a shard thread that allocates aborts.

Re-exports§

pub use table::COMMANDS;
pub use table::Spec;
pub use table::arity_ok;
pub use table::lookup;

Modules§

table
The command table: what each command is called, how many arguments it takes, where its keys are, and what COMMAND reports about it.

Structs§

Args
One command’s arguments, borrowed from the connection’s read buffer.
Client
One connection, as everybody except the connection itself sees it.
CommandStat
One command’s counters, for INFO commandstats.
Counter
A number one thread adds to and any thread may read.
Parked
Where the reply to a parked client has to go.
Server
Everything a server holds.
Session
What one connection has chosen.
Stats
The numbers INFO reports that this layer cannot see for itself.
Totals
Every thread’s Stats added together, which is what INFO answers.
Waiters
Every parked client, oldest first.

Enums§

Flow
What the connection should do after a command.
Reply
What a connection has asked to hear back, which is CLIENT REPLY.

Constants§

DATABASES
How many databases a server has.

Functions§

execute
Run one command and write its reply.
forget_session
Give back everything a connection was holding on the server.
parse_memory
Read a byte count the way CONFIG SET maxmemory reads one.
resolved
The same, for a caller that has already found the command.

Type Aliases§

StoreSource
Where a database gets its store from, asked by database number.