From ef4ec226ef720f4c3bdba5ae534465f67cda04ee Mon Sep 17 00:00:00 2001 From: tv Date: Mon, 26 Oct 2026 23:38:22 +0100 Subject: remake worker wakes up when vote is due --- src/remake/coordinator.rs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'src/remake/coordinator.rs') diff --git a/src/remake/coordinator.rs b/src/remake/coordinator.rs index 6902515..50ed4a3 100644 --- a/src/remake/coordinator.rs +++ b/src/remake/coordinator.rs @@ -17,6 +17,10 @@ //! Committing builds the snapshot at the base heads and records the new epoch, so //! every node can verify its own build against it. //! +//! It counts on every change to the records or votes, and once a second for the +//! deadline: a vote that arrives just before the deadline counts, even with a short +//! voting period. +//! //! The task lives only in memory. A coordinator that restarts takes its undecided //! remakes up again once ready (`resume`); past the voting period, that means aborting //! them. If it is gone for good, nobody decides and the proposal expires; its votes @@ -24,6 +28,7 @@ use std::time::Duration; +use tokio::sync::broadcast; use tracing::{info, warn}; use super::Host; @@ -31,7 +36,9 @@ use super::content; use super::records::{self, Decision, EpochRecord, Phase, Record}; use super::snapshot; use super::vote; +use crate::document::meta::{self, REMAKES, VOTES}; use crate::document::store::StoreError; +use crate::swarm::sync::paths_related; const TICK: Duration = Duration::from_secs(1); @@ -43,8 +50,29 @@ pub(crate) async fn run(host: H, id: String) { } info!(remake = %id, "Coordinating remake"); + let watched = [meta::path(&[REMAKES]), meta::path(&[VOTES])]; + let mut changes = host.subscribe_changes(); + let mut changes_closed = false; + let mut tick = tokio::time::interval_at(tokio::time::Instant::now() + TICK, TICK); + tick.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay); loop { - tokio::time::sleep(TICK).await; + let due = tokio::select! { + _ = tick.tick() => true, + received = changes.recv(), if !changes_closed => match received { + Ok(set) => set + .paths + .iter() + .any(|path| watched.iter().any(|dir| paths_related(path, dir))), + Err(broadcast::error::RecvError::Lagged(_)) => true, + Err(broadcast::error::RecvError::Closed) => { + changes_closed = true; + false + } + } + }; + if !due { + continue; + } match step(&host, &id).await { Ok(true) => break, -- cgit v1.3.1