Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion crates/blockchain/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ fn on_block_core(
signed_block: SignedBlock,
verify: bool,
) -> Result<(), StoreError> {
let _timing = metrics::time_fork_choice_block_processing();
let timing = metrics::time_fork_choice_block_processing();
let block_start = std::time::Instant::now();

let block = &signed_block.message;
Expand All @@ -581,6 +581,7 @@ fn on_block_core(
.has_state(&block_root)
.expect("DB read should succeed")
{
timing.discard();
return Ok(());
}

Expand Down
21 changes: 21 additions & 0 deletions crates/common/metrics/src/timing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ use std::time::Instant;
use crate::Histogram;

/// A guard that records elapsed time to a histogram when dropped.
///
/// The measurement can be cancelled with [`TimingGuard::discard`], which
/// consumes the guard without recording a sample, for a timed path that turns
/// out to be a no-op whose duration would only skew the histogram (e.g. an
/// idempotent early return).
pub struct TimingGuard {
histogram: &'static Histogram,
start: Instant,
Expand All @@ -17,6 +22,22 @@ impl TimingGuard {
start: Instant::now(),
}
}

/// Consume the guard without recording a sample.
///
/// Use when the timed work should not contribute a sample, such as a
/// duplicate/idempotent request that returns early: the elapsed time is
/// real but recording it would skew the histogram toward near-zero.
///
/// `TimingGuard` implements [`Drop`], so its fields cannot be moved out to
/// destructure it directly. Wrapping in [`std::mem::ManuallyDrop`] inhibits
/// the recording `Drop`; the fields are `Copy`, so they are then read out
/// and their copies dropped here, leaving nothing to record.
pub fn discard(self) {
let guard = std::mem::ManuallyDrop::new(self);
let _histogram = guard.histogram;
let _start = guard.start;
}
}

impl Drop for TimingGuard {
Expand Down