Skip to main content

Journal

Trait Journal 

Source
pub trait Journal: Send + Sync {
    // Required methods
    fn append(
        &self,
        entry: JournalEntry,
    ) -> impl Future<Output = Result<JournalSeq, DurableError>> + Send;
    fn read_execution(
        &self,
        id: ExecutionId,
    ) -> impl Future<Output = Result<Vec<JournalEntry>, DurableError>> + Send;
    fn read_execution_range(
        &self,
        id: ExecutionId,
        from_step_id: u32,
        limit: usize,
    ) -> impl Future<Output = Result<Vec<JournalEntry>, DurableError>> + Send;
    fn finalize(
        &self,
        id: ExecutionId,
        status: ExecutionStatus,
    ) -> impl Future<Output = Result<(), DurableError>> + Send;
    fn prune(
        &self,
        policy: &RetentionPolicy,
    ) -> impl Future<Output = Result<u64, DurableError>> + Send;
    fn sweep_orphans(
        &self,
        policy: &RetentionPolicy,
    ) -> impl Future<Output = Result<u64, DurableError>> + Send;
}
Expand description

An append-only, ordered journal of execution control flow.

Implementations are Send + Sync and route all writes through a dedicated connection so that appends are serialized. The returned futures are Send, so a journal can be shared across spawned tasks; the trait is consumed via enum dispatch, never as a trait object.

Required Methods§

Source

fn append( &self, entry: JournalEntry, ) -> impl Future<Output = Result<JournalSeq, DurableError>> + Send

Append an entry and return its database-assigned global sequence number.

§Errors

Returns DurableError::JournalUnavailable if the write cannot be acknowledged in time, or DurableError::PayloadTooLarge if a payload exceeds the configured limit.

Source

fn read_execution( &self, id: ExecutionId, ) -> impl Future<Output = Result<Vec<JournalEntry>, DurableError>> + Send

Read every entry of an execution in append order.

Intended for short executions; long executions use Journal::read_execution_range to bound memory.

§Errors

Returns DurableError::Decode if a stored entry cannot be decoded, or DurableError::JournalUnavailable if the journal cannot be read.

Source

fn read_execution_range( &self, id: ExecutionId, from_step_id: u32, limit: usize, ) -> impl Future<Output = Result<Vec<JournalEntry>, DurableError>> + Send

Read up to limit entries of an execution starting at from_step_id.

The replay cursor calls this repeatedly to walk a long execution with O(segment) memory.

§Errors

Returns DurableError::Decode if a stored entry cannot be decoded, or DurableError::JournalUnavailable if the journal cannot be read.

Source

fn finalize( &self, id: ExecutionId, status: ExecutionStatus, ) -> impl Future<Output = Result<(), DurableError>> + Send

Transition an execution to a terminal status.

Idempotent and safe to race: the transition only applies while the execution is still running, so calling this more than once for the same execution (e.g. a divergence-driven Aborted racing a caller’s own Completed/Failed) is a no-op after the first call commits — whichever status lands first wins and is never overwritten by a later one.

§Errors

Returns DurableError::JournalUnavailable if the transition cannot be committed.

Source

fn prune( &self, policy: &RetentionPolicy, ) -> impl Future<Output = Result<u64, DurableError>> + Send

Prune terminal executions according to policy and return the number of rows deleted.

Runs exclusively on a background task — never on the dispatch hot path.

§Errors

Returns DurableError::JournalUnavailable if the prune sweep cannot complete.

Source

fn sweep_orphans( &self, policy: &RetentionPolicy, ) -> impl Future<Output = Result<u64, DurableError>> + Send

Crash-orphan reclamation (#6254): flock-verify and hard-abort stale running rows.

A status='running' row whose updated_at is older than policy.stale_running_after_secs is a sweep candidate; it is only hard-aborted after a non-blocking try-acquire of its INV-15 ExecutionLock succeeds — a live owner (ExecutionLocked) short-circuits to skip, since staleness alone never proves the owner is dead (INV-17). Runs exclusively on a background task, before Journal::prune on the same tick — never on the dispatch hot path.

Returns the number of executions aborted. Returns Ok(0) without scanning when policy.stale_running_after_secs == 0 (disabled), and Ok(0) with a warn-once log on backends without a lock_dir (:memory:, Postgres, non-Unix) — a documented no-op, never a staleness-only abort.

§Errors

Returns DurableError::JournalUnavailable if the sweep cannot complete.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§