pub trait WorkloopStore:
Send
+ Sync
+ 'static {
// Required methods
fn put_workloop<'life0, 'async_trait>(
&'life0 self,
record: WorkloopRecord,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn get_workloop<'life0, 'life1, 'async_trait>(
&'life0 self,
loop_id: &'life1 WorkflowId,
) -> Pin<Box<dyn Future<Output = Result<Option<WorkloopRecord>, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn list_workloops<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<WorkloopListing, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn due_workloops<'life0, 'async_trait>(
&'life0 self,
as_of: DateTime<Utc>,
) -> Pin<Box<dyn Future<Output = Result<Vec<WorkloopRecord>, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn remove_workloop<'life0, 'life1, 'async_trait>(
&'life0 self,
loop_id: &'life1 WorkflowId,
) -> Pin<Box<dyn Future<Output = Result<bool, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn put_invariant_record<'life0, 'async_trait>(
&'life0 self,
record: InvariantStateRecord,
prune_before: DateTime<Utc>,
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn current_invariant_record<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
loop_id: &'life1 WorkflowId,
invariant: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Option<InvariantStateRecord>, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn invariant_record_generations<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
loop_id: &'life1 WorkflowId,
invariant: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<InvariantStateRecord>, StoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
}Expand description
Durable workloop persistence contract.
Required Methods§
Sourcefn put_workloop<'life0, 'async_trait>(
&'life0 self,
record: WorkloopRecord,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn put_workloop<'life0, 'async_trait>(
&'life0 self,
record: WorkloopRecord,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Create or replace a loop’s registration record.
Sourcefn get_workloop<'life0, 'life1, 'async_trait>(
&'life0 self,
loop_id: &'life1 WorkflowId,
) -> Pin<Box<dyn Future<Output = Result<Option<WorkloopRecord>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_workloop<'life0, 'life1, 'async_trait>(
&'life0 self,
loop_id: &'life1 WorkflowId,
) -> Pin<Box<dyn Future<Output = Result<Option<WorkloopRecord>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Look up one loop by id.
Sourcefn list_workloops<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<WorkloopListing, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_workloops<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<WorkloopListing, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
List decodable loops and report every undecodable row, both ordered by loop id text.
Sourcefn due_workloops<'life0, 'async_trait>(
&'life0 self,
as_of: DateTime<Utc>,
) -> Pin<Box<dyn Future<Output = Result<Vec<WorkloopRecord>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn due_workloops<'life0, 'async_trait>(
&'life0 self,
as_of: DateTime<Utc>,
) -> Pin<Box<dyn Future<Output = Result<Vec<WorkloopRecord>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Loops whose next_check_at is Some and at or before as_of — the
sweeper’s work set. A sleeping loop with a future (or absent) check
instant never appears, which is what makes a thousand sleeping loops
cost the sweeper nothing. Undecodable rows are excluded here (they
surface via WorkloopStore::list_workloops, never silently in the
hot path).
Sourcefn remove_workloop<'life0, 'life1, 'async_trait>(
&'life0 self,
loop_id: &'life1 WorkflowId,
) -> Pin<Box<dyn Future<Output = Result<bool, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn remove_workloop<'life0, 'life1, 'async_trait>(
&'life0 self,
loop_id: &'life1 WorkflowId,
) -> Pin<Box<dyn Future<Output = Result<bool, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Remove a loop’s registration (retirement). Returns whether a row existed. Invariant current-state records are NOT removed: the current record survives indefinitely by declaration (R8.1).
Sourcefn put_invariant_record<'life0, 'async_trait>(
&'life0 self,
record: InvariantStateRecord,
prune_before: DateTime<Utc>,
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn put_invariant_record<'life0, 'async_trait>(
&'life0 self,
record: InvariantStateRecord,
prune_before: DateTime<Utc>,
) -> Pin<Box<dyn Future<Output = Result<u64, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Install record as the invariant’s current record — rotating any prior
current into the generation list — and prune prior generations recorded
before prune_before, in ONE read-modify-write. Returns how many prior
generations the prune removed. The current record is never pruned; it
survives indefinitely by declaration (R8.1).
§🔴 THE INSTALL AND THE PRUNE ARE ONE COMMIT, DELIBERATELY
Both halves address the SAME key — one invariant’s slot — and the close
path performs them back to back on every park. Two separate
read-modify-write commits made a park cost 2 + 2N spine-linear
commits for N declared invariants; folding them makes it 2 + N. The
second commit read back bytes the first had just written, paid a second
durable round trip for them, and could interleave with nothing useful:
a park between them would observe a slot whose retention window had not
yet been applied. One commit removes both the cost and that window.
Retention is therefore not a separate verb that a caller could forget: installing a record IS what prunes the ones it aged out, so declared retention is retention that happens.
Sourcefn current_invariant_record<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
loop_id: &'life1 WorkflowId,
invariant: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Option<InvariantStateRecord>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn current_invariant_record<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
loop_id: &'life1 WorkflowId,
invariant: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Option<InvariantStateRecord>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
The invariant’s current record, if one was ever produced.
Sourcefn invariant_record_generations<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
loop_id: &'life1 WorkflowId,
invariant: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<InvariantStateRecord>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn invariant_record_generations<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
loop_id: &'life1 WorkflowId,
invariant: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<InvariantStateRecord>, StoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
The invariant’s prior generations within retention, oldest first.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".