pub struct DurableProcessWorker { /* private fields */ }Expand description
Reconstructable background-process worker.
Implementations§
Source§impl DurableProcessWorker
impl DurableProcessWorker
pub fn new(config: DurableProcessWorkerConfig) -> DurableProcessWorker
pub fn config(&self) -> &DurableProcessWorkerConfig
pub async fn run_process( &self, registration: ProcessRegistration, execution_context: ProcessExecutionContext, cancellation: CancellationToken, ) -> Result<ProcessAwaitOutput, PluginError>
pub async fn run_process_with_scoped_effect_controller( &self, registration: ProcessRegistration, execution_context: ProcessExecutionContext, scoped_effect_controller: ScopedEffectController<'_>, cancellation: CancellationToken, ) -> Result<ProcessAwaitOutput, PluginError>
Sourcepub async fn drive_pending_processes(&self) -> Result<(), PluginError>
pub async fn drive_pending_processes(&self) -> Result<(), PluginError>
Sweep the registry for non-terminal processes and re-execute the ones this worker can claim, driving each to a terminal state.
This is the crash-recovery counterpart to a worker that ran a process from a live turn: a trigger/trigger-started process whose worker died mid-flight is left non-terminal in the registry, and a subsequent worker reopening that registry must finish it. The sweep:
- lists every non-terminal process (
ProcessRegistry::list_non_terminal); - claims the durable single-owner
ProcessLeaseover each — a process already leased live by another owner is skipped (it is being run by that owner right now) unless persisted liveness metadata proves that owner definitely dead, in which case the lease is reclaimed with the fenced CAS discipline ofProcessRegistry::reclaim_process_lease; either way a non-terminal process is re-run by exactly one owner (lease fencing); - runs the claimed process on this worker’s wired controller, renewing the lease across the long-running execution so a healthy recovery is not swept out from under itself;
- writes the terminal outcome and releases the lease.
Idempotent by process_id: terminal processes are never in the worklist,
and a process that became terminal between the list and the claim is
detected after claiming and skipped, so re-running a recovery sweep does
not double-execute completed work.
Sourcepub async fn drain_owner_bound_work(
&self,
) -> Result<ProcessDrainReport, PluginError>
pub async fn drain_owner_bound_work( &self, ) -> Result<ProcessDrainReport, PluginError>
Graceful owner drain: terminalize this host’s own started OwnerBound
work as Abandoned{OwnerDrain} at close (ADR 0019).
This is an explicit host lever on the worker, never an implicit
consequence of closing a session. Processes are global and outlive any
one session ([ADR 0011]), so LashSession::close/park must not touch
them; a host that wants its in-flight owner-bound work terminalized at
shutdown calls this on the worker it is tearing down.
Drain sequence (the operations runbook owns the surrounding steps; this is the terminal-writing step):
- stop admitting new work to this worker;
- cancel or await the worker’s in-flight run tasks so they release their per-run leases — for Rerunnable in-flight work that is the whole story: stopping the local run task without any terminal write leaves the row non-terminal so the next worker re-runs it (its contract);
- call this lever: for every non-terminal OwnerBound row this exact
worker started (
first_started.owner == self.config.lease_owner), claim a fresh drain lease and, being the owner completing its own work, writeAbandoned{OwnerDrain}under it — the ordinary graceful completion path, respecting the single-writer rule.
A row still held by a live foreign lease (an in-flight run under one of
this worker’s own recovery incarnations that step 2 has not yet released)
is deferred rather than reclaimed, so the drain never races a still-live
run; such a row reaches Abandoned on the next drain pass or at a peer’s
recovery sweep. Rows started by a different owner, not-yet-started
OwnerBound rows (still claimable by anyone), Rerunnable rows, and
Externally-Owned rows are all left untouched.
[ADR 0011]: durable process registration is session-independent.
pub async fn request_process_cancel( &self, process_id: &str, reason: Option<String>, ) -> Result<(), PluginError>
Trait Implementations§
Source§impl Clone for DurableProcessWorker
impl Clone for DurableProcessWorker
Source§fn clone(&self) -> DurableProcessWorker
fn clone(&self) -> DurableProcessWorker
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more