aboutsummaryrefslogtreecommitdiffstats
path: root/src/remake/mod.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-05 02:58:27 +0100
committertv <tv@krebsco.de>2026-11-05 02:58:27 +0100
commitc5f67f56f46ea5c0b300a2e0eb00a7368efe4f2a (patch)
treee4a9235173e546b008fb222be12862bd0075b96e /src/remake/mod.rs
parentc10f9144b1436d4918855a657715b453a6228a44 (diff)
dashboard: add epoch switch indicator
Diffstat (limited to 'src/remake/mod.rs')
-rw-r--r--src/remake/mod.rs34
1 files changed, 27 insertions, 7 deletions
diff --git a/src/remake/mod.rs b/src/remake/mod.rs
index 2273456..b16b8a3 100644
--- a/src/remake/mod.rs
+++ b/src/remake/mod.rs
@@ -88,12 +88,21 @@ pub(crate) struct Current {
pub(crate) voters: Vec<String>,
/// The epoch's generation it remakes: a member past it switched.
pub(crate) from_generation: u64,
+ /// Committed: the wait between seeing the commit and switching
+ /// (`Proposal::switch_delay_ms`), and how much of it is left on this node (ms).
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub(crate) switch_delay_ms: Option<u64>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub(crate) switch_in_ms: Option<u64>,
}
/// The remakes of `epoch` in `doc`, with their phase at `now` (expiry by `grace`, this
-/// node's for records without their own: `Record::phase`).
+/// node's `dormant_after`, for records without their own: `Record::phase`), and for one
+/// committed, this node's wait to switch (`remake`: when it saw the commit; as
+/// `switch::check` waits: the proposal's delay, or a quarter of `grace`).
#[cfg_attr(not(feature = "dashboard"), allow(dead_code))]
pub(crate) fn current(
+ remake: &RemakeState,
doc: &Document,
epoch: Epoch,
now: crate::clock::UnixMillis,
@@ -103,12 +112,23 @@ pub(crate) fn current(
records::load_all(doc)
.into_iter()
.filter(|(_, record)| record.proposal.from_epoch == local)
- .map(|(id, record)| Current {
- phase: record.phase(now, grace),
- coordinator: record.proposal.coordinator.clone(),
- voters: record.votes.keys().cloned().collect(),
- from_generation: local.generation,
- id,
+ .map(|(id, record)| {
+ let phase = record.phase(now, grace);
+ let delay = (phase == records::Phase::Committed)
+ .then(|| record.proposal.switch_delay_ms.unwrap_or(grace / 4));
+ let left = delay.and_then(|delay| {
+ let seen = remake.seen_for(&id)?;
+ Some(delay.saturating_sub(seen.as_millis() as u64))
+ });
+ Current {
+ phase,
+ coordinator: record.proposal.coordinator.clone(),
+ voters: record.votes.keys().cloned().collect(),
+ from_generation: local.generation,
+ switch_delay_ms: delay,
+ switch_in_ms: left,
+ id,
+ }
})
.collect()
}