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

nordisk/gunnar

crates/gunnar-wire/src/stage.rs

//! Stage boundaries on the serve path, and **nothing at all** when the
//! `stages` feature is off.
//!
//! # Why the shim exists rather than `#[cfg]` at every call site
//!
//! There are eighteen boundaries across `upload_pack.rs`, `receive_pack.rs` and
//! `graph.rs`, in files several people are editing today. Eighteen `#[cfg]`
//! blocks is eighteen places a merge can go wrong and eighteen places where the
//! instrumented and uninstrumented builds could come to differ. One line each,
//! reading identically in both builds, cannot:
//!
//! ```ignore
//! let _s = crate::stage::enter("negotiate");
//! ```
//!
//! With the feature off that is `let _s = ();`, which optimises to nothing and
//! — the part that matters for measuring rather than asserting — is **not a
//! runtime check that could be wrong**. The default build has no probe rather
//! than a probe that is off.
//!
//! # Which build production runs
//!
//! `stages` is off by default, no gunnar crate turns it on, and the appliance,
//! container and service profiles the crate-layout guard witnesses resolve without
//! `gunnar-stage` in the graph at all. Only `bench/Cargo.toml` asks for it.
//! `gunnar.stage_overhead` measures the difference between the two builds
//! serving the same fetch, so the cost of instrumentation is a reported number
//! and not an assurance.

#[cfg(feature = "stages")]
pub(crate) use gunnar_stage::enter;

/// End a stage before its scope does.
///
/// Three of the boundaries fall in the middle of a function whose locals the
/// next boundary still needs, so a `{ … }` block cannot delimit them. `drop`
/// cannot be called directly at those sites: with the feature off the guard is
/// `()`, and `drop` of a `Copy` type is a `dropping_copy_types` warning — five
/// of them, in files several people are editing. This is the same call in
/// both builds.
#[cfg(feature = "stages")]
#[inline(always)]
pub(crate) fn end(guard: gunnar_stage::Guard) {
    drop(guard);
}

/// The uninstrumented guard: a ZST, so `let _s = enter(..)` costs nothing.
///
/// It is a named type rather than `()` because `let _s = ();` is
/// `clippy::let_unit_value`, which `cargo xtask ci` denies — twenty-five times,
/// once per boundary, which is exactly the eighteen-`#[cfg]`-blocks outcome the
/// module header exists to avoid. A ZST compiles to the same nothing and reads
/// the same at every call site in both builds.
#[cfg(not(feature = "stages"))]
pub(crate) struct Guard;

/// The uninstrumented boundary: takes a name, does nothing, returns a ZST.
#[cfg(not(feature = "stages"))]
#[inline(always)]
pub(crate) fn enter(_name: &'static str) -> Guard {
    Guard
}

/// The uninstrumented [`end`]. `Guard` is deliberately not `Copy`, so this is a
/// real drop and not a `dropping_copy_types` warning.
#[cfg(not(feature = "stages"))]
#[inline(always)]
pub(crate) fn end(_guard: Guard) {}