Skip to main content

DurableContext

Struct DurableContext 

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

The &self durable execution context handed to a consumer’s program.

Construct it with DurableContext::new from a shared backend (the read path) and a JournalWriterHandle (the write path) — both bound to the same durable.db. A fresh execution opens with is_resume = false; a resumed one with is_resume = true, which activates the ReplayCursor.

Implementations§

Source§

impl DurableContext

Source

pub fn new( execution_id: ExecutionId, kind: ExecutionKind, is_resume: bool, backend: Arc<DurableBackendEnum>, writer: JournalWriterHandle, config: &DurableConfig, ) -> Self

Build a context for an execution.

backend is the shared read path (the ReplayCursor reads segments through it) and must be the same durable.db instance the writer commits to. is_resume activates replay: pass true when reopening an execution that already has journal entries (as LocalBackend::open_execution reports), false for a brand-new execution.

Source

pub fn execution_id(&self) -> ExecutionId

The execution this context drives.

Source

pub fn kind(&self) -> ExecutionKind

The execution’s category.

Source

pub async fn step<T, F, Fut>( &self, desc: StepDescriptor, op: F, ) -> Result<T, DurableError>
where T: Serialize + DeserializeOwned + Send, F: FnOnce(StepHandle) -> Fut + Send, Fut: Future<Output = Result<T, StepError>> + Send,

Run a durable step, returning just its value.

On a fresh execution the operation op runs and its result is journaled; on replay the journaled result is returned and op is never invoked (INV-10). The closure receives a StepHandle carrying the step’s IdempotencyKey for boundary deduplication.

Use step_recorded when the live/replayed distinction or the step id matters.

§Errors
§Examples
use zeph_durable::StepDescriptor;

let lines: usize = ctx
    .step(StepDescriptor::idempotent("count", b"tool:count".to_vec()), |_handle| async {
        Ok(42)
    })
    .await?;
assert_eq!(lines, 42);
Source

pub async fn step_recorded<T, F, Fut>( &self, desc: StepDescriptor, op: F, ) -> Result<DurableStep<T>, DurableError>
where T: Serialize + DeserializeOwned + Send, F: FnOnce(StepHandle) -> Fut + Send, Fut: Future<Output = Result<T, StepError>> + Send,

Run a durable step, returning the full DurableStep record (id, key, and outcome).

§Errors

Identical to step.

Source

pub fn parallel(&self) -> ParallelScope<'_>

Open a ParallelScope whose children receive contiguous, eagerly-assigned step ids.

Construct the children synchronously (e.g. with a Vec or .map(...).collect()), then drive them with join_all/try_join_all; their ids are fixed by construction order and are stable across replay regardless of completion order (INV-2).

Source

pub async fn promise<T>(&self) -> Result<DurablePromise<T>, DurableError>

Create a durable promise resolved out of band by an operator or A2A reply (FR-DE-05).

The promise occupies a deterministic program position, so a resumed execution re-derives the same PromiseId and re-attaches to the pending row rather than minting an orphan. A fresh promise carries its 32-byte resolver token — hand it to the resolving channel via DurablePromise::resolver_token; a resumed promise carries none (the original token was delivered before the crash). Await the result with await_promise.

§Errors
  • DurableError::StepCapExceeded if the promise would exceed the per-execution step cap.
  • A storage error if the promise row cannot be read or inserted.
Source

pub async fn await_promise<T: DeserializeOwned>( &self, promise: DurablePromise<T>, ) -> Result<T, DurableError>

Await a durable promise’s resolved value, parking until it is resolved.

Returns immediately if the promise is already resolved (the common replay case). Otherwise it parks on an in-process notify keyed by the promise id and falls back to a database poll every promise_poll_interval_secs; above max_parked_promises concurrent waiters it polls without parking. A resolution committed by DurableHandle::resolve wakes the waiter at once.

§Errors
  • DurableError::UnknownPromise if the promise row is missing (e.g. pruned).
  • A decode/integrity error if the resolved payload cannot be opened into T.
Source

pub async fn sleep_until(&self, due: SystemTime) -> Result<(), DurableError>

Durably sleep until due, surviving a process restart (FR-DE-06).

Arms a durable_timers row at a deterministic position (so a resume re-attaches to it), then parks until the instant arrives — firing the timer itself when due, or returning at once if a restart finds it already fired or past due. The DurableTimerService, when running, fires due timers and wakes the waiter; without it, this loop still makes progress on its own.

§Errors
  • DurableError::StepCapExceeded if the timer would exceed the per-execution step cap.
  • A storage error if the timer cannot be armed or its state read.
Source

pub fn resolver_handle(&self) -> DurableHandle

Build an out-of-band DurableHandle over this context’s backend.

The handle is the operator/A2A resolution surface; it MUST NOT be exposed to an LLM tool (INV-9). It shares the same backend, so a resolution it commits wakes an await_promise parked on the same process at once.

Source

pub async fn drain_background(&self)

Await any in-flight background checkpoint folds — a turn-boundary / test barrier.

The soft step-cap fold runs on a spawned task so it never blocks step dispatch; call this at a turn boundary to ensure the journal is compacted before the next phase observes it.

Trait Implementations§

Source§

impl Debug for DurableContext

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. 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> 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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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