Skip to main content

DurableProcessWorker

Struct DurableProcessWorker 

Source
pub struct DurableProcessWorker { /* private fields */ }
Expand description

Reconstructable background-process worker.

Implementations§

Source§

impl DurableProcessWorker

Source

pub fn new(config: DurableProcessWorkerConfig) -> Self

Source

pub fn from_shared_config(config: Arc<DurableProcessWorkerConfig>) -> Self

Source

pub fn config(&self) -> &DurableProcessWorkerConfig

Source

pub async fn run_process( &self, registration: ProcessRegistration, execution_context: ProcessExecutionContext, cancellation: CancellationToken, ) -> Result<ProcessAwaitOutput, PluginError>

Source

pub async fn run_process_with_scoped_effect_controller( &self, registration: ProcessRegistration, execution_context: ProcessExecutionContext, scoped_effect_controller: ScopedEffectController<'_>, cancellation: CancellationToken, ) -> Result<ProcessAwaitOutput, PluginError>

Source

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:

  1. lists every non-terminal process (ProcessRegistry::list_non_terminal);
  2. claims the durable single-owner ProcessLease over 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 of ProcessRegistry::reclaim_process_lease; either way a non-terminal process is re-run by exactly one owner (lease fencing);
  3. 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;
  4. 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.

Source

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):

  1. stop admitting new work to this worker;
  2. 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);
  3. 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, write Abandoned{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.

Source

pub async fn request_process_cancel( &self, process_id: &str, reason: Option<String>, ) -> Result<(), PluginError>

Trait Implementations§

Source§

impl Clone for DurableProcessWorker

Source§

fn clone(&self) -> DurableProcessWorker

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more