pub struct Wire<S> { /* private fields */ }Expand description
The engine: connections on one side, the command layer on the other.
One per shard thread, and it is two halves rather than one thing. The front
is the connections and everything they own, which never leaves the thread
that accepted them. Server is the databases, and it is what a second
thread would come to share. This type is where the two meet, and every
method on it that is not a one line delegation is a method that genuinely
needs both: running a command, answering a client that blocked, and
forgetting a client that has gone.
Implementations§
Source§impl<S: Sink> Wire<S>
impl<S: Sink> Wire<S>
Sourcepub fn with_server(server: Server, sink: S) -> Wire<S>
pub fn with_server(server: Server, sink: S) -> Wire<S>
An engine over a server the caller built, which is how a test gives it a clock it can move by hand.
Sourcepub const fn server_mut(&mut self) -> &mut Server
pub const fn server_mut(&mut self) -> &mut Server
The same, for a caller that owns both ends.
Sourcepub fn set_limits(&mut self, limits: Limits)
pub fn set_limits(&mut self, limits: Limits)
Change the protocol limits, which is proto-max-bulk-len and friends.
Sourcepub fn hangup(&mut self, conn: ConnId)
pub fn hangup(&mut self, conn: ConnId)
The peer went away.
Whatever is buffered for it is dropped rather than written, and the slot comes back as soon as the commands already framed out of its buffer have run, because those commands’ arguments still point into it.
Sourcepub fn owed(&self) -> usize
pub fn owed(&self) -> usize
Connections with a reply that has not gone out yet.
Non zero means a socket was full and what is left is being held for a later flush, which a driver waiting on readability needs to know: there is work here that no incoming byte will ever wake it up for.
Sourcepub fn stopping(&self) -> bool
pub fn stopping(&self) -> bool
Whether a client has asked the server to stop.
The driver reads this once a turn, next to the flag a signal sets, and
leaves its loop when either is set. Asked after the batch rather than
during it, so the SHUTDOWN and everything that shared its batch is
finished and written out before anything closes.
Sourcepub fn decoders(&self) -> usize
pub fn decoders(&self) -> usize
Decoders in the pool, which is the high water mark of one batch.
Sourcepub fn buffer_bytes(&self) -> usize
pub fn buffer_bytes(&self) -> usize
What every connection’s read and reply buffers are holding.
Sourcepub fn feed(&mut self, conn: ConnId, bytes: &[u8])
pub fn feed(&mut self, conn: ConnId, bytes: &[u8])
Take bytes off a connection and frame whatever commands they complete.
Anything left over stays in the connection’s buffer, half a command included, so the caller hands over whatever the socket gave it without looking at it.
Sourcepub fn take_ready(&mut self, into: &mut Vec<Cmd>, max: usize) -> usize
pub fn take_ready(&mut self, into: &mut Vec<Cmd>, max: usize) -> usize
Move up to max framed commands into into.
The reactor wants a batch it owns, and the front keeps the buffers, so what crosses between them is this: numbers, no borrows.
Sourcepub fn tick(&mut self)
pub fn tick(&mut self)
Take a clock reading for the whole batch.
04 section 5: once per turn, never per command, so every command in a
batch compares against the same millisecond and two keys written
together expire together.
Sourcepub fn maintain(&mut self) -> Option<usize>
pub fn maintain(&mut self) -> Option<usize>
Do one batch’s worth of housekeeping.
Today that is one segment of arena compaction at most, which is what
stops a server that rewrites the same keys from holding every version of
them. It is separate from Wire::tick because the clock has to move
before a batch runs and this does not: it can wait until the replies are
out, and the driver decides when that is.
Per batch and not per turn of the loop. A turn can carry one command or a thousand, so a per turn call means the rate at which garbage is collected has nothing to do with the rate at which it is made, and on a saturated server the second one wins. That was measured: with this on the loop’s turn the server settled at seven segments for six segments’ worth of keys, which is where an unloaded process running the same writes settled at six.
Trait Implementations§
Source§impl<S: Sink> Engine for Wire<S>
impl<S: Sink> Engine for Wire<S>
Source§fn key_hash(&self, cmd: &Cmd) -> Option<u64>
fn key_hash(&self, cmd: &Cmd) -> Option<u64>
None when it touches none. Read moreSource§fn prefetch(&self, cmd: &Cmd, hash: u64)
fn prefetch(&self, cmd: &Cmd, hash: u64)
run is about to load for this work. Read more