aboutsummaryrefslogtreecommitdiffstats
path: root/src/remake
diff options
context:
space:
mode:
Diffstat (limited to 'src/remake')
-rw-r--r--src/remake/local.rs6
-rw-r--r--src/remake/mod.rs34
2 files changed, 33 insertions, 7 deletions
diff --git a/src/remake/local.rs b/src/remake/local.rs
index c80a5a5..e13c6fd 100644
--- a/src/remake/local.rs
+++ b/src/remake/local.rs
@@ -253,6 +253,12 @@ impl RemakeState {
.or_insert_with(Instant::now)
}
+ /// How long ago this node first saw remake `id` committed (`first_seen`), if it did.
+ #[cfg_attr(not(feature = "dashboard"), allow(dead_code))]
+ pub(crate) fn seen_for(&self, id: &str) -> Option<std::time::Duration> {
+ self.lock().first_seen.get(id).map(|at| at.elapsed())
+ }
+
pub(crate) fn status(&self, id: &str) -> Option<LocalStatus> {
self.lock().status.get(id).cloned()
}
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()
}