pub struct Timings {
pub bind_grace: Duration,
pub probe_timeout: Duration,
pub join_timeout: Duration,
pub busy_grace: Duration,
pub read_deadline: Duration,
pub idle: Duration,
}Expand description
The timings above are the defaults. What a process actually judges a lease contest by is
declared in .ai/repo/policy.yaml’s server: block and read once, here.
They were compiled constants until 2026-09-15: unchangeable without a rebuild, stated
nowhere a reader would look, and invisible to every projection — while probe_timeout is
the number that decides whether a live but slow owner keeps its lease or is taken over
while it is still serving. That is a decision about how this repository is supervised, not
an implementation detail, so it belongs in the model.
A OnceLock, because a process reads one policy: the repository is opened once and the
answer must not change underneath a contest that is already being judged. Absent keys keep
the constants, so a policy that cannot be read does not silently change behaviour.
use majordomus_cli::lease::{
Timings, BIND_GRACE, BUSY_GRACE, IDLE, JOIN_TIMEOUT, PROBE_TIMEOUT, READ_DEADLINE,
};
// the defaults are the compiled constants, one for one
let t = Timings::default();
assert_eq!(t.bind_grace, BIND_GRACE);
assert_eq!(t.probe_timeout, PROBE_TIMEOUT);
assert_eq!(t.join_timeout, JOIN_TIMEOUT);
assert_eq!(t.busy_grace, BUSY_GRACE);
assert_eq!(t.read_deadline, READ_DEADLINE);
assert_eq!(t.idle, IDLE);
// a busy owner is given up on before the election that waits on it gives up itself
assert!(t.busy_grace < t.join_timeout);Fields§
§bind_grace: Durationserver.bind_grace_seconds:
probe_timeout: Durationserver.probe_timeout_seconds:
join_timeout: Durationserver.join_timeout_seconds:
busy_grace: Durationserver.busy_grace_seconds:
read_deadline: Durationserver.read_deadline_seconds:
idle: Durationserver.idle_seconds:
Implementations§
Source§impl Timings
impl Timings
Sourcepub fn from_policy(policy: &ServerPolicy) -> Self
pub fn from_policy(policy: &ServerPolicy) -> Self
What a declaration means, as a value rather than as a side effect.
The mapping is the part that can be wrong; the OnceLock below is plumbing. Kept
separate so it can be tested directly — a test that went through the lock would
depend on which test ran first, since a process reads one policy by construction.
use majordomus_cli::lease::Timings;
use majordomus_cli::policy::ServerPolicy;
use std::time::Duration;
// an empty declaration keeps every default
assert_eq!(Timings::from_policy(&ServerPolicy::default()), Timings::default());
// and a declared value is the one used, rather than the constant
let declared = ServerPolicy {
probe_timeout_seconds: Some(9),
..ServerPolicy::default()
};
let t = Timings::from_policy(&declared);
assert_eq!(t.probe_timeout, Duration::from_secs(9));
assert_ne!(t.probe_timeout, Timings::default().probe_timeout);
// the keys it says nothing about are untouched
assert_eq!(t.bind_grace, Timings::default().bind_grace);
// the idle timeout is declared beside the others (I2701)
let declared = ServerPolicy { idle_seconds: Some(3), ..ServerPolicy::default() };
assert_eq!(Timings::from_policy(&declared).idle, Duration::from_secs(3));Trait Implementations§
impl Copy for Timings
impl Eq for Timings
impl StructuralPartialEq for Timings
Auto Trait Implementations§
impl Freeze for Timings
impl RefUnwindSafe for Timings
impl Send for Timings
impl Sync for Timings
impl Unpin for Timings
impl UnsafeUnpin for Timings
impl UnwindSafe for Timings
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.