perf-sentinel-core 0.7.3

Core library for perf-sentinel: polyglot performance anti-pattern detector
Documentation
//! Shared Scaphandre state and monotonic timestamp helper.
//!
//! Thin wrapper around [`AgedEnergyMap`] generated by the
//! [`impl_energy_state!`] macro. This file keeps `ScaphandreState` as a
//! distinct nominal type (so the daemon code cannot accidentally swap a
//! cloud-energy state for a Scaphandre one) while delegating all storage
//! behavior to the shared impl.

/// Row type expected by [`super::ops::apply_scrape`] when constructing
/// fresh entries. Aliased to the shared [`EnergyRow`] so both states
/// share one definition.
///
/// [`EnergyRow`]: crate::score::energy_state::EnergyRow
pub(super) use crate::score::energy_state::EnergyRow as ServiceEnergy;

crate::score::energy_state::impl_energy_state! {
    /// Runtime state shared between the scraper task and the scoring path.
    ///
    /// Nominally distinct from
    /// [`crate::score::cloud_energy::CloudEnergyState`] so the daemon can
    /// accept one without accidentally receiving the other. Both wrap the
    /// same [`AgedEnergyMap`] storage under the hood.
    #[derive(Debug, Default)]
    pub struct ScaphandreState;
}

/// Monotonic milliseconds since process start.
///
/// Uses `Instant::now()` relative to a lazily-initialized epoch so the
/// values are small and safe for `u64` arithmetic for years. Shared by
/// both Scaphandre and cloud-energy scrapers so the scoring path has a
/// single time source.
pub fn monotonic_ms() -> u64 {
    use std::sync::OnceLock;
    use std::time::Instant;

    static EPOCH: OnceLock<Instant> = OnceLock::new();
    let epoch = EPOCH.get_or_init(Instant::now);
    let elapsed = epoch.elapsed();
    #[allow(clippy::cast_possible_truncation)]
    {
        elapsed.as_millis() as u64
    }
}

#[cfg(test)]
mod tests {
    use super::monotonic_ms;

    #[test]
    fn monotonic_ms_increases() {
        let a = monotonic_ms();
        std::thread::sleep(std::time::Duration::from_millis(2));
        let b = monotonic_ms();
        assert!(b > a);
    }
}