pub struct Screen {Show 21 fields
pub facts: Facts,
pub hostname: Option<String>,
pub addresses: Vec<IfAddr>,
pub dns: Option<Vec<Ipv4Addr>>,
pub cpu_model: Option<String>,
pub cpus: usize,
pub cpu_percent: Option<u8>,
pub load1: Option<String>,
pub memory: Option<(u64, u64)>,
pub disk: Option<(u64, u64)>,
pub explode: Option<(u64, u64)>,
pub disk_kind: Option<DiskKind>,
pub writer: Option<&'static str>,
pub uptime_secs: Option<u64>,
pub now_unix: u64,
pub rows: VecDeque<Row>,
pub dropped: u64,
pub index: Vec<Row>,
pub standby: Vec<Row>,
pub tenants: Vec<Row>,
pub flow: Vec<Row>,
/* private fields */
}Expand description
Everything the frame is drawn from.
Fields§
§facts: Facts§hostname: Option<String>§addresses: Vec<IfAddr>§dns: Option<Vec<Ipv4Addr>>What /etc/resolv.conf names, read each tick: None = no file.
On the host line as dns a, b / dns none, because a box that can
spell an address and not a name looks healthy from every other row
(measured 2026-09-08: two re-images to learn github.com did not
resolve).
cpu_model: Option<String>§cpus: usize§cpu_percent: Option<u8>§load1: Option<String>§memory: Option<(u64, u64)>(total, available) bytes.
disk: Option<(u64, u64)>§explode: Option<(u64, u64)>The exploded read cache, summed over every open repository:
(used, budget). Named on the band because it is the one number on the
box that grows with READS rather than with pushes, and because an
operator looking at a full /data needs to know which part of it the
server will give back on its own. None until the first tick with an
engine.
disk_kind: Option<DiskKind>What the data root IS (4×75G raid0 xfs); None = say nothing.
writer: Option<&'static str>The writer arm the stores append through (uring / safe), after
the first store opened; None = say nothing.
uptime_secs: Option<u64>§now_unix: u64§rows: VecDeque<Row>§dropped: u64Lines the tap could not buffer (logtap::dropped), shown when > 0.
index: Vec<Row>The index rows: one per repository with a pack being resolved,
re-sampled every tick and drawn between the band and the event list —
index alice/linux 34% 4.7M/13.9M resolve 2.1 GB/s. Information,
never a gate: the tick reads a few atomics and nothing else.
standby: Vec<Row>The standby rows, one per configured replication target, drawn
with the index rows between the band and the event list:
standby standby synced 105 failed 40 last 00:00:03 ago
!standby standby synced 0 failed 8 last successful replication: NEVERThe ! is the staleness alarm. Nothing on this box said anything at all
while every configured standby received NOTHING for weeks; this row is
the answer to that, and the never wording is deliberately its own
sentence — see crate::replication_view::StandbyRow::describe.
tenants: Vec<Row>The tenants row (metered only): tenants paid N grace N suspended N, re-sampled every tick like the standby rows and drawn
with them. Empty when nothing fills Facts::tenants.
flow: Vec<Row>The flow row: flow in 4.2 GiB out 1.1 GiB today · silent 3 of 12. The other half of the tenants band, and the half that exists on
every build — what the tenants are DOING, beside what they are paying.
Its own Vec rather than a second entry in Screen::tenants so that
the two can be sampled from two different sources and either can be
absent alone: a community box draws this row and no tenants row, and a
metered box before the first flush draws the tenants row and not this
one.
Implementations§
Source§impl Screen
impl Screen
pub fn new(facts: Facts) -> Self
Sourcepub fn sample_tenants(&mut self, counts: Option<TenantCounts>)
pub fn sample_tenants(&mut self, counts: Option<TenantCounts>)
Re-derive the tenants row. Public so the render test can feed it
counts without an entitlement slot. None draws nothing — the
community band must not show a row of zeros on a box that cannot know.
Any suspended tenant makes it a WARN row: that is revenue not arriving.
Sourcepub fn sample_flow(&mut self, fleet: Option<Fleet>)
pub fn sample_flow(&mut self, fleet: Option<Fleet>)
Re-derive the flow row. Public so the render test can feed it a
fold without a store. None draws nothing — before the first flush has
folded anything there is no number, and a row of zeroes would say the
box served nobody today, which is a claim and not an absence.
A silent tenant is a WARN row for the same reason a suspended one is: it is revenue that has stopped arriving, and it is the one an operator can still do something about.
Sourcepub fn sample_replication(&mut self, report: &ReplicationReport)
pub fn sample_replication(&mut self, report: &ReplicationReport)
Re-derive the standby rows, and raise the staleness alarm.
Public so a render test can feed it a report without a replicator — which is the only way the never row can be asserted at all, since a standby that has never synced is precisely a standby nobody can stand up in a test.
Sourcepub fn sample_index(&mut self, facts: &[IndexFacts], now: Instant)
pub fn sample_index(&mut self, facts: &[IndexFacts], now: Instant)
Re-derive the index rows from the engine’s counters. Public so a
test can feed it facts without an engine.
Sourcepub fn push(&mut self, row: Row)
pub fn push(&mut self, row: Row)
Append a row, dropping the oldest past EVENT_ROWS.
Sourcepub fn render_frame(&self, cols: usize, rows: usize) -> String
pub fn render_frame(&self, cols: usize, rows: usize) -> String
The whole frame: cursor home, every row padded to cols - 1, closed
with ESC[K (erase to end of line) and joined with \r\n, exactly
rows rows. cols - 1 and not cols: a full-width row leaves the
VT’s deferred-wrap flag set and the next \n would then eat a line.
ESC[K is what clears the LAST column the padding never reaches:
MEASURED on UpCloud 2026-08-29, column 80 kept stale glyphs of the
serve log the band overpainted. Erase-to-EOL clears it without
writing a character there, so the wrap flag stays clear.
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for Screen
impl !UnwindSafe for Screen
impl Freeze for Screen
impl Send for Screen
impl Sync for Screen
impl Unpin for Screen
impl UnsafeUnpin for Screen
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request