pub trait ProcessRegistry: Send + Sync {
Show 31 methods
// Required methods
fn register_process<'life0, 'async_trait>(
&'life0 self,
registration: ProcessRegistration,
) -> Pin<Box<dyn Future<Output = Result<ProcessRecord, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn set_external_ref<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
external_ref: ProcessExternalRef,
) -> Pin<Box<dyn Future<Output = Result<ProcessRecord, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn grant_handle<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
session_scope: &'life1 SessionScope,
process_id: &'life2 str,
descriptor: ProcessHandleDescriptor,
) -> Pin<Box<dyn Future<Output = Result<ProcessHandleGrant, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn revoke_handle<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
session_scope: &'life1 SessionScope,
process_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn transfer_handle_grants<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
from_scope: &'life1 SessionScope,
to_scope: &'life2 SessionScope,
process_ids: &'life3 [String],
) -> Pin<Box<dyn Future<Output = Result<(), PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
fn list_handle_grants<'life0, 'life1, 'async_trait>(
&'life0 self,
session_scope: &'life1 SessionScope,
) -> Pin<Box<dyn Future<Output = Result<Vec<ProcessHandleGrantEntry>, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn handle_grants_for_process<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<ProcessHandleGrant>, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn delete_session_process_state<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<ProcessSessionDeleteReport, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn append_event<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
request: ProcessEventAppendRequest,
) -> Pin<Box<dyn Future<Output = Result<ProcessEventAppendResult, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn events_after<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
after_sequence: u64,
) -> Pin<Box<dyn Future<Output = Result<Vec<ProcessEvent>, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn wake_events_after<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
after_sequence: u64,
) -> Pin<Box<dyn Future<Output = Result<Vec<ProcessEvent>, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn complete_process<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
await_output: ProcessAwaitOutput,
) -> Pin<Box<dyn Future<Output = Result<ProcessRecord, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn record_first_started<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
started: ProcessStarted,
) -> Pin<Box<dyn Future<Output = Result<ProcessRecord, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn request_process_abandon<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
request: AbandonRequest,
) -> Pin<Box<dyn Future<Output = Result<ProcessRecord, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn set_process_wait<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
wait: WaitState,
) -> Pin<Box<dyn Future<Output = Result<ProcessRecord, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn clear_process_wait<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<ProcessRecord, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn get_process<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Option<ProcessRecord>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn list_processes<'life0, 'life1, 'async_trait>(
&'life0 self,
filter: &'life1 ProcessListFilter,
) -> Pin<Box<dyn Future<Output = Result<Vec<ProcessRecord>, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn ack_wake<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
sequence: u64,
) -> Pin<Box<dyn Future<Output = Result<(), PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn list_non_terminal<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<ProcessRecord>, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn claim_process_lease<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
owner: &'life2 LeaseOwnerIdentity,
lease_ttl_ms: u64,
) -> Pin<Box<dyn Future<Output = Result<ProcessLeaseClaimOutcome, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn reclaim_process_lease<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
owner: &'life2 LeaseOwnerIdentity,
observed_holder: &'life3 ProcessLease,
lease_ttl_ms: u64,
) -> Pin<Box<dyn Future<Output = Result<ProcessLeaseClaimOutcome, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
fn renew_process_lease<'life0, 'life1, 'async_trait>(
&'life0 self,
lease: &'life1 ProcessLease,
lease_ttl_ms: u64,
) -> Pin<Box<dyn Future<Output = Result<ProcessLease, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn get_process_lease<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<ProcessLease>, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn complete_process_lease<'life0, 'life1, 'async_trait>(
&'life0 self,
completion: &'life1 ProcessLeaseCompletion,
) -> Pin<Box<dyn Future<Output = Result<(), PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn prune_terminal_processes<'life0, 'async_trait>(
&'life0 self,
cutoff_epoch_ms: u64,
) -> Pin<Box<dyn Future<Output = Result<ProcessPruneReport, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
// Provided methods
fn durability_tier(&self) -> DurabilityTier { ... }
fn list_live_handle_grants<'life0, 'life1, 'async_trait>(
&'life0 self,
session_scope: &'life1 SessionScope,
) -> Pin<Box<dyn Future<Output = Result<Vec<ProcessHandleGrantEntry>, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn has_handle_grant<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
session_scope: &'life1 SessionScope,
process_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<bool, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn count_events_through<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
event_type: &'life2 str,
up_to_sequence: u64,
) -> Pin<Box<dyn Future<Output = Result<u64, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn recent_events<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
limit: usize,
) -> Pin<Box<dyn Future<Output = Result<Vec<ProcessEvent>, PluginError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
}Expand description
Durability-neutral process registry.
Process waits are coordination behavior and live on
ProcessWorkDriver /
ProcessAwaiter, not on persistence
implementations. Registry methods are point reads and writes only. See
docs/adr/0016-process-waits-live-on-the-work-driver-seam.md.
Required Methods§
fn register_process<'life0, 'async_trait>(
&'life0 self,
registration: ProcessRegistration,
) -> Pin<Box<dyn Future<Output = Result<ProcessRecord, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Sourcefn set_external_ref<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
external_ref: ProcessExternalRef,
) -> Pin<Box<dyn Future<Output = Result<ProcessRecord, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn set_external_ref<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
external_ref: ProcessExternalRef,
) -> Pin<Box<dyn Future<Output = Result<ProcessRecord, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Attach a durable backend reference to a registered process.
Implementations must reject unknown process ids. The first assignment stores the reference. Repeating the exact same assignment is an idempotent no-op that returns the existing record unchanged. Assigning a different reference after one has been stored is a registry model error.
fn grant_handle<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
session_scope: &'life1 SessionScope,
process_id: &'life2 str,
descriptor: ProcessHandleDescriptor,
) -> Pin<Box<dyn Future<Output = Result<ProcessHandleGrant, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn revoke_handle<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
session_scope: &'life1 SessionScope,
process_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn transfer_handle_grants<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
from_scope: &'life1 SessionScope,
to_scope: &'life2 SessionScope,
process_ids: &'life3 [String],
) -> Pin<Box<dyn Future<Output = Result<(), PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn list_handle_grants<'life0, 'life1, 'async_trait>(
&'life0 self,
session_scope: &'life1 SessionScope,
) -> Pin<Box<dyn Future<Output = Result<Vec<ProcessHandleGrantEntry>, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn handle_grants_for_process<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<ProcessHandleGrant>, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn delete_session_process_state<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<ProcessSessionDeleteReport, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn append_event<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
request: ProcessEventAppendRequest,
) -> Pin<Box<dyn Future<Output = Result<ProcessEventAppendResult, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn events_after<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
after_sequence: u64,
) -> Pin<Box<dyn Future<Output = Result<Vec<ProcessEvent>, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn wake_events_after<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
after_sequence: u64,
) -> Pin<Box<dyn Future<Output = Result<Vec<ProcessEvent>, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn complete_process<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
await_output: ProcessAwaitOutput,
) -> Pin<Box<dyn Future<Output = Result<ProcessRecord, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Sourcefn record_first_started<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
started: ProcessStarted,
) -> Pin<Box<dyn Future<Output = Result<ProcessRecord, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn record_first_started<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
started: ProcessStarted,
) -> Pin<Box<dyn Future<Output = Result<ProcessRecord, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Record the durable, lease-fenced “execution started” fact (ADR 0019).
First-writer-wins: the first call stores started; a later call is an
idempotent no-op returning the existing record unchanged (the fact is
immutable once written, so the sweep can prove an OwnerBound row has
begun executing). Implementations reject unknown process ids.
Sourcefn request_process_abandon<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
request: AbandonRequest,
) -> Pin<Box<dyn Future<Output = Result<ProcessRecord, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn request_process_abandon<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
request: AbandonRequest,
) -> Pin<Box<dyn Future<Output = Result<ProcessRecord, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Set the durable, non-terminal Abandon Request marker (ADR 0019).
First-writer-wins: if a marker is already present the call is an idempotent no-op returning the existing record unchanged, preserving the original recorded authorization rather than letting a later requester clobber it. Setting it on a terminal row is a model error — a terminal process has already recorded its outcome, so there is nothing to abandon.
fn set_process_wait<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
wait: WaitState,
) -> Pin<Box<dyn Future<Output = Result<ProcessRecord, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn clear_process_wait<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<ProcessRecord, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_process<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Option<ProcessRecord>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn list_processes<'life0, 'life1, 'async_trait>(
&'life0 self,
filter: &'life1 ProcessListFilter,
) -> Pin<Box<dyn Future<Output = Result<Vec<ProcessRecord>, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn ack_wake<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
sequence: u64,
) -> Pin<Box<dyn Future<Output = Result<(), PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Sourcefn list_non_terminal<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<ProcessRecord>, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_non_terminal<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<ProcessRecord>, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
All non-terminal process records, in stable process_id order.
This is the recovery sweep’s worklist: every process that was started
but has not reached a terminal event is a candidate for re-execution by
a DurableProcessWorker after a crash.
Terminal processes are excluded — they are already done and idempotent by
process_id, so re-running them would be wasted work.
Sourcefn claim_process_lease<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
owner: &'life2 LeaseOwnerIdentity,
lease_ttl_ms: u64,
) -> Pin<Box<dyn Future<Output = Result<ProcessLeaseClaimOutcome, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn claim_process_lease<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
owner: &'life2 LeaseOwnerIdentity,
lease_ttl_ms: u64,
) -> Pin<Box<dyn Future<Output = Result<ProcessLeaseClaimOutcome, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Claim the durable single-owner lease over a non-terminal process.
An unexpired lease held by a different owner returns
ProcessLeaseClaimOutcome::Busy carrying the observed holder;
claiming a free or expired lease succeeds and bumps the
fencing_token, and the same incarnation re-entering its own live
lease extends it without changing token or fence. The returned
ProcessLease’s (owner, lease_token) plus fencing_token are the
contract a worker presents on every subsequent renew/complete — a stale
writer is rejected.
Sourcefn reclaim_process_lease<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
owner: &'life2 LeaseOwnerIdentity,
observed_holder: &'life3 ProcessLease,
lease_ttl_ms: u64,
) -> Pin<Box<dyn Future<Output = Result<ProcessLeaseClaimOutcome, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn reclaim_process_lease<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
owner: &'life2 LeaseOwnerIdentity,
observed_holder: &'life3 ProcessLease,
lease_ttl_ms: u64,
) -> Pin<Box<dyn Future<Output = Result<ProcessLeaseClaimOutcome, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Reclaim an unexpired process lease whose observed holder is definitely dead according to persisted local-process liveness metadata.
Mirrors
RuntimePersistence::reclaim_session_execution_lease:
backends must CAS on observed_holder (owner identity, lease token,
and fencing token) so a stale claimant cannot clear a newer live lease
that won the race after the busy observation, and a successful reclaim
must advance the fencing token monotonically.
Sourcefn renew_process_lease<'life0, 'life1, 'async_trait>(
&'life0 self,
lease: &'life1 ProcessLease,
lease_ttl_ms: u64,
) -> Pin<Box<dyn Future<Output = Result<ProcessLease, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn renew_process_lease<'life0, 'life1, 'async_trait>(
&'life0 self,
lease: &'life1 ProcessLease,
lease_ttl_ms: u64,
) -> Pin<Box<dyn Future<Output = Result<ProcessLease, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Extend the expiry of a live lease the caller still owns.
The lease must match the persisted (owner, lease_token, fencing_token)
and be unexpired, else the renewal is rejected (the lease was superseded
or expired). Workers renew across long-running effects so a healthy
process is not swept out from under its live owner.
Sourcefn get_process_lease<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<ProcessLease>, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_process_lease<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<ProcessLease>, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Read the current lease row for a process without claiming it.
Returns the persisted lease when one is held (owner and token present),
or None when the row is unleased or released. The returned lease may be
expired: expiry is a raw fact exposed read-side (ADR 0019) so hosts
classify staleness themselves; this never mutates the lease. Unknown
process ids return None.
Sourcefn complete_process_lease<'life0, 'life1, 'async_trait>(
&'life0 self,
completion: &'life1 ProcessLeaseCompletion,
) -> Pin<Box<dyn Future<Output = Result<(), PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn complete_process_lease<'life0, 'life1, 'async_trait>(
&'life0 self,
completion: &'life1 ProcessLeaseCompletion,
) -> Pin<Box<dyn Future<Output = Result<(), PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Release a lease the caller owns, fenced by the completion’s
(process_id, lease_token).
Mirrors clearing a runtime turn lease: a stale completion (whose token no longer matches the live lease) is a no-op so it cannot release a lease a newer owner now holds. Idempotent — completing an already-released lease succeeds.
Sourcefn prune_terminal_processes<'life0, 'async_trait>(
&'life0 self,
cutoff_epoch_ms: u64,
) -> Pin<Box<dyn Future<Output = Result<ProcessPruneReport, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn prune_terminal_processes<'life0, 'async_trait>(
&'life0 self,
cutoff_epoch_ms: u64,
) -> Pin<Box<dyn Future<Output = Result<ProcessPruneReport, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Physically delete terminal process rows whose updated_at_ms is older
than cutoff_epoch_ms, together with their events, wake acks, handle
grants, and lease rows. Host-scheduled retention: hosts that project
results/events into their own store call this to keep the registry
bounded. Non-terminal rows are never touched. Callers must choose a
retention window comfortably longer than any waiter lifetime — a
pruned process id becomes “unknown process” to late awaits.
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use lash_core::{PluginError, ProcessRegistry};
async fn prune_week_old(registry: &dyn ProcessRegistry) -> Result<(), PluginError> {
let now_ms = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("clock after epoch")
.as_millis() as u64;
// Window must exceed any in-flight await's lifetime (ADR 0017).
let cutoff = now_ms - Duration::from_secs(7 * 24 * 60 * 60).as_millis() as u64;
let report = registry.prune_terminal_processes(cutoff).await?;
eprintln!(
"pruned {} processes, {} events",
report.pruned_processes, report.pruned_events
);
Ok(())
}Provided Methods§
Sourcefn durability_tier(&self) -> DurabilityTier
fn durability_tier(&self) -> DurabilityTier
Durability tier this process registry provides; defaults to
DurabilityTier::Inline.
fn list_live_handle_grants<'life0, 'life1, 'async_trait>(
&'life0 self,
session_scope: &'life1 SessionScope,
) -> Pin<Box<dyn Future<Output = Result<Vec<ProcessHandleGrantEntry>, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn has_handle_grant<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
session_scope: &'life1 SessionScope,
process_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<bool, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Sourcefn count_events_through<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
event_type: &'life2 str,
up_to_sequence: u64,
) -> Pin<Box<dyn Future<Output = Result<u64, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn count_events_through<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
event_type: &'life2 str,
up_to_sequence: u64,
) -> Pin<Box<dyn Future<Output = Result<u64, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Count events of event_type with sequence <= up_to_sequence.
This is the signal-ordinal query: the Nth occurrence of a signal event resolves the Nth durable wait key. The default scans the event log; store backends override it with a COUNT so per-signal cost stays flat instead of growing with a long-lived process’s history.
Sourcefn recent_events<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
limit: usize,
) -> Pin<Box<dyn Future<Output = Result<Vec<ProcessEvent>, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn recent_events<'life0, 'life1, 'async_trait>(
&'life0 self,
process_id: &'life1 str,
limit: usize,
) -> Pin<Box<dyn Future<Output = Result<Vec<ProcessEvent>, PluginError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
The most recent limit events, in ascending sequence order.
Observation snapshots use this to show a bounded activity tail without fetching a process’s entire history on every poll. The default scans the event log; store backends override it with ORDER BY … LIMIT.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".