pub struct Server {
pub stats: Stats,
/* private fields */
}Expand description
Everything a server holds.
One of these per shard thread, not one per process: the databases inside are
not Sync and are reached by sending their thread a command. What makes
this a server rather than a shard is that it is the whole of what a
connection can address.
Fields§
§stats: StatsThe numbers the reactor keeps for INFO.
Implementations§
Source§impl Server
impl Server
Sourcepub const fn waiters_mut(&mut self) -> &mut Waiters
pub const fn waiters_mut(&mut self) -> &mut Waiters
The same, for the engine, which is what binds and forgets them.
Sourcepub fn serve_waiter(&mut self, at: usize, now: u64, out: &mut Out) -> bool
pub fn serve_waiter(&mut self, at: usize, now: u64, out: &mut Out) -> bool
Try to answer the waiter at at, writing into the buffer the engine
found for it, and say whether it is finished with.
The engine cannot reach the databases and this cannot reach the connections, so the two meet here: the caller hands in one connection’s reply buffer and gets back whether to unpark the client behind it.
§Panics
If at is not a waiter.
Source§impl Server
impl Server
Sourcepub fn with_clock(clock: Clock) -> Server
pub fn with_clock(clock: Clock) -> Server
A server on a clock the caller moves by hand, for tests.
Sourcepub fn db(&mut self, i: usize) -> &mut Keyspace
pub fn db(&mut self, i: usize) -> &mut Keyspace
One database, by index.
§Panics
If i is not a database. SELECT is the only way a client changes the
index and it checks, so an index that is out of range here is a bug in
the caller and not something a client can ask for.
Sourcepub fn db_ref(&self, i: usize) -> &Keyspace
pub fn db_ref(&self, i: usize) -> &Keyspace
One database, by index, without taking it mutably.
What the prefetch stage needs. It runs for all 64 commands in a batch
before any of them executes, so it cannot hold the mutable borrow run
is about to want, and it does not need one: warming a cache line reads
nothing and changes nothing.
§Panics
As Server::db.
Sourcepub fn refresh_clock(&mut self)
pub fn refresh_clock(&mut self)
Take a new clock reading and give it to every database.
Once per turn of the event loop, which is the only place time moves. A
command asking what the time is gets the answer the whole batch got, so
two keys written by the same batch expire together (04 section 3).
Sourcepub fn set_clock_ms(&mut self, ms: u64)
pub fn set_clock_ms(&mut self, ms: u64)
Move every clock here to ms by hand, for tests about expiry.
A test cannot wait a hundred seconds and a test that waits a hundred
milliseconds is a test that fails on a loaded machine, so time moves on
request. The system clock underneath will overwrite this on the next
Server::refresh_clock, which is why this is only useful in a test
that drives commands directly rather than through the event loop.
Sourcepub fn uptime_secs(&self) -> u64
pub fn uptime_secs(&self) -> u64
Seconds since this server was built.
Sourcepub fn memory_bytes(&self) -> usize
pub fn memory_bytes(&self) -> usize
Bytes held by every database’s index and arena, plus the read and reply buffers of every connection.
The buffers are in here because they are real and because Redis counts its own, so leaving them out would make the one number people compare flattering rather than true. They are not a database, so nothing in the keyspace can change them and the engine has to say when they move.
Sourcepub fn dataset_bytes(&self) -> usize
pub fn dataset_bytes(&self) -> usize
What the keyspace itself is holding, live records only.
used_memory minus this is what the store costs to run: the index, the
space dead records are sitting in until compaction gets to them, and the
connections’ buffers.
Sourcepub fn arena_bytes(&self) -> usize
pub fn arena_bytes(&self) -> usize
Bytes the arenas are holding, live and dead together.
Sourcepub fn index_bytes(&self) -> usize
pub fn index_bytes(&self) -> usize
Bytes the indexes are holding.
Sourcepub fn segment_count(&self) -> usize
pub fn segment_count(&self) -> usize
Arena segments whose pages are real, across every database.
Sourcepub const fn conn_bytes(&self) -> usize
pub const fn conn_bytes(&self) -> usize
What the connections’ read and reply buffers are holding.
Sourcepub fn note_conn_bytes(&mut self, delta: isize)
pub fn note_conn_bytes(&mut self, delta: isize)
Note that the connections are holding delta bytes more than they were,
or fewer when it is negative.
A delta and not a total because the alternative is a walk over every
connection, and the walk would have to happen on a turn of the loop
rather than when INFO asks, which puts the cost of a report on the
command path of a server nobody is asking.
Sourcepub fn expired_keys(&self) -> u64
pub fn expired_keys(&self) -> u64
Keys reclaimed by running into them after their deadline.
Sourcepub fn compact_step(&mut self) -> Option<usize>
pub fn compact_step(&mut self) -> Option<usize>
Give one database’s dead space back, if any database has enough of it to
be worth the move. None when no database had a candidate.
Once per batch, next to the clock. Overwriting a key writes a new record and counts the old one dead, so without this a server holds everything it has ever written: 400000 sets over 100000 keys measured at 742 bytes a key against Redis at 144 for the same load, and the whole difference was dead records nothing ever came back for.
At most one segment moves per call and the search starts one database further along each time, so the cost of asking is a comparison per database and the cost of acting is bounded by a segment.