Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/nornir

examples/code_room_consume_bench.rs

//! Times a FULL read of a workspace into a fresh code room: every member
//! consumed by the real driver, one line per commit with the phase split
//! (compile / read-back / second pass / delta / lake write) and the units
//! (compiled now / fresh), then the totals.
//!
//! ```text
//! NORNIR_MIMIR_DRIVER=/path/to/cargo-mimir-dump \
//! [NORNIR_MIMIR_TARGET=per-member] \
//! cargo run --release --no-default-features --features code-room \
//!   --example code_room_consume_bench -- <builds-dir> <members-file>
//! ```
//! `<members-file>`: one member per line, `name source-dir branch sha` (the
//! source is a git clone holding `sha`). No feeds run (the dump pipeline
//! only). `<builds-dir>` should be empty for a cold read.

#[cfg(feature = "code-room")]
fn main() -> anyhow::Result<()> {
    use std::time::Instant;

    use nornir::code_room::CodeRoom;
    use nornir::code_room::consumer_loop::{DriverDumpers, Event, Member, Request};

    let mut args = std::env::args().skip(1);
    let builds = std::path::PathBuf::from(args.next().expect("usage: code_room_consume_bench <builds-dir> <members-file>"));
    // absolute, as on a server: the driver runs IN the member's tree
    std::fs::create_dir_all(&builds)?;
    let builds = builds.canonicalize()?;
    let list = std::fs::read_to_string(args.next().expect("<members-file>"))?;
    let members: Vec<Member> = list
        .lines()
        .map(str::trim)
        .filter(|l| !l.is_empty() && !l.starts_with('#'))
        .map(|l| {
            let w: Vec<&str> = l.split_whitespace().collect();
            Member { name: w[0].to_string(), source: w[1].into(), branch: Some(w[2].to_string()), head: w[3].to_string() }
        })
        .collect();
    // every member's head must be its branch tip in its source: a stale line
    // reads another commit than the file says (and leaves the member out of
    // the super build) — refused, by name
    let stale: Vec<String> = members
        .iter()
        .filter_map(|m| {
            let branch = m.branch.as_deref().unwrap_or("HEAD");
            let o = std::process::Command::new("git").arg("-C").arg(&m.source).args(["rev-parse", branch]).output().ok()?;
            let tip = String::from_utf8_lossy(&o.stdout).trim().to_string();
            (tip != m.head).then(|| format!("{} ({branch} is at {}, the file says {})", m.name, &tip[..tip.len().min(10)], &m.head[..m.head.len().min(10)]))
        })
        .collect();
    if !stale.is_empty() {
        anyhow::bail!("the members file is stale — fix these lines: {}", stale.join("; "));
    }
    let dumpers = DriverDumpers(nornir::code_room::driver::Settings::from_env().probe().map_err(|r| anyhow::anyhow!("{}", r.note))?);
    let room = CodeRoom::new("bench", &builds);
    let t0 = Instant::now();
    let mut sums = [0u64; 8];
    let mut on = |e: Event<'_>| match e {
        Event::Member { member, behind } => eprintln!("[{:>6.1}s] {member}: {behind} commit(s) behind", t0.elapsed().as_secs_f32()),
        Event::Commit { member, report: r } => {
            let p = &r.phase_ms;
            let d = p.dump_detail.unwrap_or_default();
            for (i, v) in [p.dump, d.cargo_ms, d.read_ms, d.retry_ms, p.delta, p.commit, d.compiled, d.fresh].into_iter().enumerate() {
                sums[i] += v;
            }
            println!(
                "{member:<16} {:>8} ms  dump {:>7} (cargo {:>7} read {:>6} retry {:>6})  delta {:>6}  commit {:>6}  units {:>5} compiled {:>5} fresh {:>5} recompiled {:>4}  {} crates +{} {}{}",
                r.ms, p.dump, d.cargo_ms, d.read_ms, d.retry_ms, p.delta, p.commit, d.units, d.compiled, d.fresh, d.recompiled, r.crates_dumped, r.rows_plus, r.status, r.error.as_deref().map(|e| format!(" — {e}")).unwrap_or_default()
            );
        }
        Event::Std { toolchain, outcome, ms } => eprintln!("std of {toolchain}: {} in {ms} ms", if outcome.is_ok() { "ok" } else { "failed" }),
        _ => {}
    };
    // `MIMIR_BENCH_ONLY=<member>`: every member's clone is made, one is read
    let only = std::env::var("MIMIR_BENCH_ONLY").ok().filter(|v| !v.is_empty());
    // `MIMIR_BENCH_AFFECTED=1`: only what a change reaches (`only: Affected`)
    let affected = std::env::var("MIMIR_BENCH_AFFECTED").is_ok_and(|v| v == "1");
    let report = room
        .consume(&dumpers, &[], &Request { members: &members, only: only.as_deref(), affected, ..Default::default() }, &mut on)
        .map_err(|r| anyhow::anyhow!("{}", r.note))?;
    println!(
        "TOTAL {} ms over {} member(s): dump {} (cargo {} read {} retry {}) delta {} commit {} · units compiled {} fresh {} · failed members {}",
        t0.elapsed().as_millis(),
        report.members.len(),
        sums[0],
        sums[1],
        sums[2],
        sums[3],
        sums[4],
        sums[5],
        sums[6],
        sums[7],
        report.failed().len()
    );
    for c in &report.checked {
        println!("  checked {}", c.line());
    }
    for m in &report.members {
        if let Some(e) = &m.error {
            println!("  {} FAILED: {e}", m.member);
        }
    }
    Ok(())
}

#[cfg(not(feature = "code-room"))]
fn main() {
    eprintln!("build with --features code-room");
}