pub struct WorkloopService { /* private fields */ }Expand description
The engine-side cadence service. One instance, one sweep task, N loops.
Implementations§
Source§impl WorkloopService
impl WorkloopService
Sourcepub fn new(
store: Arc<dyn WorkloopStore>,
sink: Arc<dyn LoopEventSink>,
waker: Arc<dyn WorkloopWaker>,
sweep_interval: Duration,
) -> Result<Self, WorkloopError>
pub fn new( store: Arc<dyn WorkloopStore>, sink: Arc<dyn LoopEventSink>, waker: Arc<dyn WorkloopWaker>, sweep_interval: Duration, ) -> Result<Self, WorkloopError>
Creates the service. sweep_interval is the operator-declared sweep
cadence — REQUIRED, never defaulted, and it bounds dead-man detection
latency.
§Errors
Refuses a zero interval (WorkloopError::ZeroSweepInterval).
Sourcepub fn with_clock(
store: Arc<dyn WorkloopStore>,
sink: Arc<dyn LoopEventSink>,
waker: Arc<dyn WorkloopWaker>,
sweep_interval: Duration,
now: impl Fn() -> DateTime<Utc> + Send + Sync + 'static,
) -> Result<Self, WorkloopError>
pub fn with_clock( store: Arc<dyn WorkloopStore>, sink: Arc<dyn LoopEventSink>, waker: Arc<dyn WorkloopWaker>, sweep_interval: Duration, now: impl Fn() -> DateTime<Utc> + Send + Sync + 'static, ) -> Result<Self, WorkloopError>
WorkloopService::new with an injected clock, for deterministic
tests.
§Errors
Refuses a zero interval (WorkloopError::ZeroSweepInterval).
Sourcepub const fn sweep_interval(&self) -> Duration
pub const fn sweep_interval(&self) -> Duration
The declared sweep interval.
Sourcepub async fn register(
&self,
loop_id: WorkflowId,
namespace: String,
spec: WorkloopSpec,
) -> Result<WorkloopRecord, WorkloopError>
pub async fn register( &self, loop_id: WorkflowId, namespace: String, spec: WorkloopSpec, ) -> Result<WorkloopRecord, WorkloopError>
Registers a loop: persists its declared spec and arms the first cadence window (and/or duration deadlines) on the sweep set.
§Errors
Refuses a duplicate registration and propagates store failures.
Sourcepub async fn wake_now(&self, loop_id: &WorkflowId) -> Result<(), WorkloopError>
pub async fn wake_now(&self, loop_id: &WorkflowId) -> Result<(), WorkloopError>
Wakes a loop’s current generation immediately — the signal-armed fire (R2.4): a declared signal arrived, so the iteration runs now, no window involved.
§Errors
Propagates the waker’s failure.
Sourcepub async fn deregister(
&self,
loop_id: &WorkflowId,
) -> Result<bool, WorkloopError>
pub async fn deregister( &self, loop_id: &WorkflowId, ) -> Result<bool, WorkloopError>
Deregisters a loop (retirement or death). Invariant current-state records are untouched — the current record survives indefinitely (R8.1).
§Errors
Propagates store failures.
Sourcepub async fn note_iteration_closed(
&self,
loop_id: &WorkflowId,
samples: &[HealthSample],
) -> Result<Vec<InvariantAlarm>, WorkloopError>
pub async fn note_iteration_closed( &self, loop_id: &WorkflowId, samples: &[HealthSample], ) -> Result<Vec<InvariantAlarm>, WorkloopError>
Feed an iteration close into health accounting (R3.3): every declared
invariant is sampled on the same tick — Confirmed resets its
accounting, Unconfirmed accrues red-sample evidence and may exceed
the count-form tolerance immediately. Returns the alarms raised.
§Errors
Refuses samples naming undeclared invariants; propagates store and append failures.
Sourcepub async fn tick(&self) -> Result<SweepReport, WorkloopError>
pub async fn tick(&self) -> Result<SweepReport, WorkloopError>
One sweep pass over every due loop: fire elapsed cadence windows
(recording CadenceFired through the one Recorder, then waking the
generation), evaluate the dead-man switch (an iteration with no
terminal by its next window is a missed window — R3.3a — counted
against every invariant), and evaluate every declared tolerance,
raising InvariantUnconfirmed with its cause on the one alarm path.
§Errors
Returns an error only when the due-set itself cannot be read; per-loop faults are carried in the report so one sick loop cannot silence the sweep for the rest.