Add cube-bench (correctness-gated microbenchmarks) + daemon stats telemetry

- cube-bench crate: real-code-path throughput/latency over cubestore,
  cubecrypt (aes/gcm/chacha/xts), cubecode VM, and cubesys Session.
  Every section asserts correctness before timing. Wired into ./check
  as an opt-in 'bench' stage.
- cubesys Session: per-command latency histogram + per-C-namespace record
  counts, exposed via a new 'stats' command over the live socket.
- Deployed rebuilt cube-server to /home/luulu/.cubelinux/bin and
  restarted the system cube.service; verified stats live.
This commit is contained in:
cube-agent
2026-08-11 01:15:32 -04:00
parent 06ea3252eb
commit 4f9cb2e75e
6 changed files with 529 additions and 2 deletions
+89 -1
View File
@@ -13,10 +13,25 @@ use cubecode::{CodeCell, Kind, Op, Vm};
use cubecoords::CubeHeader;
use cubecrypt::{CubeEnv, KeySlot, Selector, TransformId};
use cubestore::{CubeStore, HashBackend};
use std::collections::BTreeMap;
use std::time::Instant;
/// Per-command latency accumulator (cumulative; the daemon reports these via
/// the `stats` command). Counts and sums are exact; mean/max are derived.
#[derive(Default, Clone)]
struct CmdStat {
count: u64,
total_ns: u128,
max_ns: u128,
}
/// One cube command session: a store plus the command interpreter.
pub struct Session {
store: CubeStore<HashBackend>,
/// Total commands executed since this session started (telemetry).
calls: u64,
/// Per top-level command latency histogram (command name -> stats).
per_cmd: BTreeMap<String, CmdStat>,
}
impl Default for Session {
@@ -30,6 +45,8 @@ impl Session {
pub fn new() -> Self {
Session {
store: CubeStore::new(HashBackend::new()),
calls: 0,
per_cmd: BTreeMap::new(),
}
}
@@ -43,12 +60,83 @@ impl Session {
&mut self.store
}
/// Snapshot of the session's telemetry: total commands serviced, per-command
/// latency distribution (mean/max in µs), and the occupancy of each `C`
/// namespace (number of records whose class axis equals `c`).
///
/// This is the "substantive" telemetry the daemon exposes — not just a
/// health ping. A monitoring pass can sample `stats` repeatedly and derive
/// request rates and latency histograms from the cumulative counters.
pub fn stats(&self) -> String {
let mut lines = Vec::new();
lines.push(format!("total commands serviced: {}", self.calls));
// per-command latency distribution
lines.push("per-command latency (µs, mean / max / count):".into());
if self.per_cmd.is_empty() {
lines.push(" (no commands timed yet)".into());
} else {
for (name, st) in &self.per_cmd {
let mean_us = if st.count > 0 {
(st.total_ns as f64) / (st.count as f64) / 1e3
} else {
0.0
};
let max_us = st.max_ns as f64 / 1e3;
lines.push(format!(
" {:<8} mean {:8.2} max {:8.2} n={}",
name, mean_us, max_us, st.count
));
}
}
// per-C namespace occupancy (C axis 0 = Null control space)
let keys = self.store.keys();
let mut by_c: BTreeMap<u8, usize> = BTreeMap::new();
for k in &keys {
*by_c.entry(k.c).or_insert(0) += 1;
}
lines.push(format!("records by C namespace ({} total):", keys.len()));
if by_c.is_empty() {
lines.push(" (store empty)".into());
} else {
for (c, n) in &by_c {
let label = if *c == 0 { "Null(0)" } else { "" };
lines.push(format!(" C={c:<3} {n:>6} records {label}"));
}
}
lines.join("\n")
}
/// Execute one command line. `Ok(out)` is a (possibly multi-line) result to
/// print; `Err(e)` is a human-readable error.
/// print; `Err(e)` is a human-readable error. Also records per-command
/// latency into the session telemetry (see [`Session::stats`]).
pub fn exec(&mut self, line: &str) -> Result<String, String> {
let t0 = Instant::now();
let cmd_name = line.split_whitespace().next().unwrap_or("").to_string();
let result = self.exec_inner(line);
// record telemetry regardless of ok/err (a failed command is still a
// serviced command and worth timing).
self.calls += 1;
let st = self.per_cmd.entry(cmd_name).or_default();
let elapsed = t0.elapsed().as_nanos();
st.count += 1;
st.total_ns += elapsed;
if elapsed > st.max_ns {
st.max_ns = elapsed;
}
result
}
/// The real interpreter (separated so [`exec`] can wrap it with timing).
fn exec_inner(&mut self, line: &str) -> Result<String, String> {
let mut it = line.split_whitespace();
let cmd = it.next().ok_or_else(|| "empty line".to_string())?;
match cmd {
"stats" => {
// Substantive telemetry: command volume + latency distribution
// + per-C-namespace record occupancy. This is what makes the
// daemon measurable, not merely "healthy".
Ok(self.stats())
}
"prog" => {
let path = it.next().ok_or_else(|| "prog needs <path>".to_string())?;
let mut ops: Vec<Op> = Vec::new();