38 lines
1.5 KiB
Rust
38 lines
1.5 KiB
Rust
|
|
//! Server-start-time utilities for stale-merge detection.
|
||
|
|
|
||
|
|
/// Wall-clock time captured the first time this server process touches the
|
||
|
|
/// merge subsystem. Used to detect merge_jobs left over from a previous
|
||
|
|
/// server instance: a re-exec on `rebuild_and_restart` keeps the same PID,
|
||
|
|
/// so PID alone cannot distinguish "current" vs "previous" server. This
|
||
|
|
/// timestamp is fresh per-process (the static is reset by execve) and is
|
||
|
|
/// the source of truth for stale-merge detection.
|
||
|
|
static SERVER_START_TIME: std::sync::OnceLock<f64> = std::sync::OnceLock::new();
|
||
|
|
|
||
|
|
/// Return this server process's start time (lazily captured on first call).
|
||
|
|
pub(crate) fn server_start_time() -> f64 {
|
||
|
|
*SERVER_START_TIME.get_or_init(unix_now)
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Encode the current server's start-time into the CRDT `error` field for
|
||
|
|
/// a Running merge job.
|
||
|
|
pub(crate) fn encode_server_start_time(t: f64) -> String {
|
||
|
|
format!("{{\"server_start\":{t}}}")
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Decode the server-start-time from a Running merge job's `error` field.
|
||
|
|
/// Returns `None` for legacy entries (which encoded `pid` instead) — those
|
||
|
|
/// are treated as stale by the cleanup pass.
|
||
|
|
pub(crate) fn decode_server_start_time(error: Option<&str>) -> Option<f64> {
|
||
|
|
error
|
||
|
|
.and_then(|e| serde_json::from_str::<serde_json::Value>(e).ok())
|
||
|
|
.and_then(|v| v["server_start"].as_f64())
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Current Unix timestamp in seconds as `f64`.
|
||
|
|
pub(crate) fn unix_now() -> f64 {
|
||
|
|
std::time::SystemTime::now()
|
||
|
|
.duration_since(std::time::UNIX_EPOCH)
|
||
|
|
.unwrap_or_default()
|
||
|
|
.as_secs_f64()
|
||
|
|
}
|