Skip to main content

rust_mc_status/core/
time.rs

1//! Monotonic latency measurement for protocol implementations.
2//!
3//! Uses [`tokio::time::Instant`] instead of [`std::time::SystemTime`] because:
4//!
5//! - `Instant` is **monotonic** — it never goes backwards, even when the
6//!   system clock is adjusted by NTP or the user.
7//! - `SystemTime` can go backwards on clock corrections, which would cause
8//!   `elapsed()` to return an error or a negative duration.
9//! - `Instant` has no epoch — it cannot be serialised or compared across
10//!   process restarts, but that is fine here since we only measure short
11//!   durations within a single ping.
12//!
13//! # Usage
14//!
15//! ```rust,ignore
16//! use rust_mc_status::core::time::{start_timer, elapsed_ms};
17//!
18//! let start = start_timer();
19//! // … network operation …
20//! let latency = elapsed_ms(start); // f64, always ≥ 0
21//! ```
22
23use tokio::time::Instant;
24
25/// Record the start of a latency measurement.
26///
27/// Returns a [`tokio::time::Instant`] that should be passed to [`elapsed_ms`]
28/// after the operation completes.
29///
30/// # Example
31///
32/// ```rust,ignore
33/// let start = start_timer();
34/// do_something().await;
35/// let ms = elapsed_ms(start);
36/// ```
37#[inline]
38pub fn start_timer() -> Instant {
39    Instant::now()
40}
41
42/// Return elapsed milliseconds since `start` as `f64`.
43///
44/// Always returns a non-negative value — the underlying monotonic clock
45/// guarantees that `Instant::elapsed` never goes backwards.
46///
47/// # Example
48///
49/// ```rust,ignore
50/// let start = start_timer();
51/// do_something().await;
52/// println!("{:.2} ms", elapsed_ms(start));
53/// ```
54#[inline]
55pub fn elapsed_ms(start: Instant) -> f64 {
56    start.elapsed().as_secs_f64() * 1000.0
57}