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§
Sourcefn append(
&self,
entry: JournalEntry,
) -> impl Future<Output = Result<JournalSeq, DurableError>> + Send
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.
Sourcefn read_execution(
&self,
id: ExecutionId,
) -> impl Future<Output = Result<Vec<JournalEntry>, DurableError>> + Send
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.
Sourcefn read_execution_range(
&self,
id: ExecutionId,
from_step_id: u32,
limit: usize,
) -> 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
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.
Sourcefn finalize(
&self,
id: ExecutionId,
status: ExecutionStatus,
) -> impl Future<Output = Result<(), DurableError>> + Send
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.
Sourcefn prune(
&self,
policy: &RetentionPolicy,
) -> impl Future<Output = Result<u64, DurableError>> + Send
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.
Sourcefn sweep_orphans(
&self,
policy: &RetentionPolicy,
) -> impl Future<Output = Result<u64, DurableError>> + Send
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".