summaryrefslogtreecommitdiffstats
path: root/src/clock.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-10-26 05:38:41 +0100
committertv <tv@krebsco.de>2026-10-26 05:38:41 +0100
commitf12a839d6e6bdd29a86ac52d5de836519a41aaf0 (patch)
treeb34da34a22292793c991b15a95908f6cd78bb70b /src/clock.rs
parent504435444c65efc59c0f7c6881991296258538a7 (diff)
wrap unix timestamps in newtype
Diffstat (limited to 'src/clock.rs')
-rw-r--r--src/clock.rs48
1 files changed, 44 insertions, 4 deletions
diff --git a/src/clock.rs b/src/clock.rs
index dafd44b..7613930 100644
--- a/src/clock.rs
+++ b/src/clock.rs
@@ -7,6 +7,46 @@
//! isn't affected.
use std::sync::atomic::{AtomicI64, Ordering};
+use std::time::Duration;
+
+use serde::{Deserialize, Serialize};
+
+/// A point in time as Unix milliseconds, as stored in the document and reported: not a
+/// duration (those are `Duration`, or plain milliseconds named `…_ms`). Comparable
+/// across nodes as far as their clocks agree; for elapsed time within a node use
+/// tokio's `Instant`.
+#[derive(
+ Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
+)]
+#[serde(transparent)]
+pub(crate) struct UnixMillis(pub(crate) u64);
+
+impl UnixMillis {
+ pub(crate) fn as_u64(self) -> u64 {
+ self.0
+ }
+
+ /// `ms` milliseconds later (saturating).
+ pub(crate) fn plus_ms(self, ms: u64) -> Self {
+ Self(self.0.saturating_add(ms))
+ }
+
+ /// `duration` later (saturating, to the millisecond).
+ pub(crate) fn plus(self, duration: Duration) -> Self {
+ self.plus_ms(u64::try_from(duration.as_millis()).unwrap_or(u64::MAX))
+ }
+
+ /// Milliseconds from `earlier` to this; 0 if `earlier` is later.
+ pub(crate) fn ms_since(self, earlier: Self) -> u64 {
+ self.0.saturating_sub(earlier.0)
+ }
+}
+
+impl std::fmt::Display for UnixMillis {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ self.0.fmt(f)
+ }
+}
/// The node's wall clock: the system clock plus an offset (zero outside tests).
#[derive(Debug, Default)]
@@ -15,10 +55,10 @@ pub(crate) struct Clock {
}
impl Clock {
- /// Now, in Unix milliseconds.
- pub(crate) fn now_millis(&self) -> u64 {
+ /// Now.
+ pub(crate) fn now_millis(&self) -> UnixMillis {
let offset = self.offset_ms.load(Ordering::Relaxed);
- system_millis().saturating_add_signed(offset)
+ UnixMillis(system_millis().saturating_add_signed(offset))
}
/// Puts this clock `offset_ms` ahead of the system clock (behind if negative).
@@ -46,7 +86,7 @@ mod tests {
let before = clock.now_millis();
clock.set_offset_ms(3_600_000);
let ahead = clock.now_millis();
- assert!(ahead >= before + 3_600_000);
+ assert!(ahead >= before.plus_ms(3_600_000));
clock.set_offset_ms(-3_600_000);
assert!(clock.now_millis() < before);
}