Expand description
Saving/loading timestamps to disk
Storing timestamps on disk is not so straightforward. We need to use wall clock time in order to survive restarts. But wall clocks can be wrong, so we need at least to apply some sanity checks.
This module encapsulates those checks, and some error handling choices.
It allows Instant
s to be used while the system is running,
with bespoke types for loading/saving.
See Loading::load_future
for the load/save guarantees provided.
The initial entrypoints are Storing::start
and Loading::start
.
Granularity is 1 second and the precise rounding behaviour is not specified.
§Data model
To mitigate clock skew, we store the wall clock time at which
each timestamp was saved to disk (Reference
)
and the offset from now to that timestamp (FutureTimestamp
).
The same storage time can be used for multiple timestamps that are stored together.
§Example
use serde::{Serialize, Deserialize};
use std::time::{Duration, Instant};
use tor_rtcompat::{PreferredRuntime, SleepProvider as _};
use crate::time_store;
let runtime = PreferredRuntime::create().unwrap();
#[derive(Serialize, Deserialize, Debug)]
struct Stored {
time_ref: time_store::Reference,
t0: time_store::FutureTimestamp,
}
let t0: Instant = runtime.now() + Duration::from_secs(60);
let storing = time_store::Storing::start(&runtime);
let data = Stored {
time_ref: storing.store_ref(),
t0: storing.store_future(t0),
};
let json = serde_json::to_string(&data).unwrap();
// later:
let data: Stored = serde_json::from_str(&json).unwrap();
let loading = time_store::Loading::start(&runtime, data.time_ref);
let t0: Instant = loading.load_future(data.t0);
assert!(t0 - runtime.now() <= Duration::from_secs(60));
§Time arithmetic overflows and stupid system time settings
Arithmetic is done with signed 64-bit numbers of seconds. So overflow cannot occur unless the clock is completely ludicrous. If the clock is ludicrous, time calculations are going to be a mess. We treat this as clock skew, using saturating arithmetic, rather than returning errors. Reasonable operation will resume when the clock becomes sane.
Macros§
- derive_
deftly_ 🔒template_ RawConversions - Define
as_raw
andfrom_raw
methods (for a struct with a single field) - derive_
deftly_ 🔒template_ Serde String OrTransparent - Define
Serialize
andDeserialize
via string rep or transparently, depending
Structs§
- Deserialize
Future 🔒Timestamp String Visitor - Visitor for deserializing from a string
- Deserialize
Reference 🔒String Visitor - Visitor for deserializing from a string
- Future
Timestamp - Representation of an absolute time, in the future, suitable for storing to disk
- Loading
- Context for loading
Instant
s from disk - Now 🔒
- The two notions of the current time, for internal use
- Parse
Error - Error parsing a timestamp or reference
- Reference
- On-disk representation of a reference time, used as context for stored timestamps
- Storing
- Context for storing
Instant
s to disk
Functions§
- system_
time_ 🔒max - Maximum value of SystemTime
- system_
time_ 🔒min - Minimum value of SystemTime
- system_
time_ 🔒to_ time_ t - Convert a
SystemTime
to ani64
time_t
- time_
t_ 🔒to_ system_ time - Convert a
SystemTime
to ani64
time_t