Skip to content
Merged
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
25 changes: 18 additions & 7 deletions crates/blockchain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,6 @@ impl BlockChainServer {
return;
}

// Observe tick interval duration. Done after the idempotency guard so a
// skipped duplicate tick doesn't shorten the next real tick's sample.
if let Some(prev_instant) = self.last_tick_instant {
metrics::observe_tick_interval_duration(prev_instant.elapsed());
}
self.last_tick_instant = Some(Instant::now());

// Update current slot metric
metrics::update_current_slot(slot);
self.update_sync_status(slot);
Expand Down Expand Up @@ -1186,6 +1179,24 @@ pub(crate) trait BlockChainProtocol: Send + Sync {
impl BlockChainServer {
#[send_handler]
async fn handle_tick(&mut self, _msg: block_chain_protocol::Tick, ctx: &Context<Self>) {
// Observe the interval between tick-handler invocations here, at the
// scheduler level, so a sample is taken for *every* tick — including the
// ones `on_tick` drops via its idempotency guard. The main case is the
// interval-0 tick after a proposer builds the next block one interval
// early: the build advances the store clock to interval 0, so that tick
// is skipped. Recording only inside `on_tick` (after the guard) would
// miss it, so the following tick's sample would span two intervals and
// show a false ~1.6s spike in `lean_tick_interval_duration_seconds` even
// though ticks are firing on their ~800ms cadence.
//
// Ticks that fire early from wall-clock drift and are then guard-skipped
// are also sampled here; that only adds occasional sub-interval samples,
// which is acceptable for a metric meant to surface *late* ticks.
if let Some(prev_instant) = self.last_tick_instant {
metrics::observe_tick_interval_duration(prev_instant.elapsed());
}
self.last_tick_instant = Some(Instant::now());

let now_ms = unix_now_ms();
self.on_tick(now_ms, ctx).await;

Expand Down