Skip to main content

KernelJournal

Trait KernelJournal 

Source
pub trait KernelJournal: Send + Sync {
    // Required methods
    fn stage_outbound_envelope<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        operation_id: &'life1 str,
        envelope_json: &'life2 str,
    ) -> Pin<Box<dyn Future<Output = JournalResult<()>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn read_outbound_envelope<'life0, 'life1, 'async_trait>(
        &'life0 self,
        operation_id: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = JournalResult<Option<String>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn clear_outbound_envelope<'life0, 'life1, 'async_trait>(
        &'life0 self,
        operation_id: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = JournalResult<()>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn compare_and_append<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        operation_id: &'life1 str,
        expected_head: Option<&'life2 str>,
        record: JournalRecordInput,
    ) -> Pin<Box<dyn Future<Output = JournalResult<JournalAppendReceipt>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn head<'life0, 'life1, 'async_trait>(
        &'life0 self,
        operation_id: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = JournalResult<Option<JournalHead>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn read_from<'life0, 'life1, 'async_trait>(
        &'life0 self,
        operation_id: &'life1 str,
        from_step_seq: u64,
    ) -> Pin<Box<dyn Future<Output = JournalResult<Vec<JournalEntry>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn records_after<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        operation_id: &'life1 str,
        after_head: Option<&'life2 str>,
    ) -> Pin<Box<dyn Future<Output = JournalResult<Vec<JournalEntry>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn compare_and_install_checkpoint<'life0, 'life1, 'life2, 'life3, 'async_trait>(
        &'life0 self,
        operation_id: &'life1 str,
        previous_checkpoint_id: Option<&'life2 str>,
        covered_head: &'life3 str,
        checkpoint: CheckpointCandidate,
    ) -> Pin<Box<dyn Future<Output = JournalResult<InstalledCheckpoint>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             'life3: 'async_trait;
    fn latest_checkpoint<'life0, 'life1, 'async_trait>(
        &'life0 self,
        operation_id: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = JournalResult<Option<InstalledCheckpoint>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn ack_checkpoint<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        operation_id: &'life1 str,
        checkpoint_id: &'life2 str,
    ) -> Pin<Box<dyn Future<Output = JournalResult<InstalledCheckpoint>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn prune_acked_prefix<'life0, 'life1, 'async_trait>(
        &'life0 self,
        operation_id: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = JournalResult<JournalPruneReceipt>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
}
Expand description

The durable transaction capability (spec §9.1). Deliberately not part of super::session_log::SessionLog (§9.4).

Guarantees an implementation owes (spec §9.1):

  • strict ordering within an operation;
  • a failed CAS never overwrites;
  • record bytes preserved verbatim;
  • checkpoint pointer advances monotonically;
  • the checkpoint store verifies covered_head against through_step_seq but does not require it to still be the current transaction head (§22.14);
  • checkpoint pointer and prefix pruning have an explicit acknowledgement boundary.

Required Methods§

Source

fn stage_outbound_envelope<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, operation_id: &'life1 str, envelope_json: &'life2 str, ) -> Pin<Box<dyn Future<Output = JournalResult<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Persist the byte-identical canonical input envelope before attempting its record append.

A wake replays this value rather than constructing a fresh envelope, preserving the caller’s idempotency key and observed clock across the append crash window.

Source

fn read_outbound_envelope<'life0, 'life1, 'async_trait>( &'life0 self, operation_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = JournalResult<Option<String>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Return the staged outbound envelope, if an append-before crash left one behind.

Source

fn clear_outbound_envelope<'life0, 'life1, 'async_trait>( &'life0 self, operation_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = JournalResult<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Clear a staged outbound envelope after its input is durably owned or rejected.

Source

fn compare_and_append<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, operation_id: &'life1 str, expected_head: Option<&'life2 str>, record: JournalRecordInput, ) -> Pin<Box<dyn Future<Output = JournalResult<JournalAppendReceipt>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Atomically append record iff the operation’s head is exactly expected_head.

expected_head == None starts the chain (genesis; record.step_seq must be 0).

Errors: JournalError::CasConflict when the head moved or a genesis already exists; JournalError::Integrity when step_seq does not follow the head; JournalError::Io on storage failure.

Source

fn head<'life0, 'life1, 'async_trait>( &'life0 self, operation_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = JournalResult<Option<JournalHead>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

The current head, or None when the operation has no records and no pruned anchor.

Source

fn read_from<'life0, 'life1, 'async_trait>( &'life0 self, operation_id: &'life1 str, from_step_seq: u64, ) -> Pin<Box<dyn Future<Output = JournalResult<Vec<JournalEntry>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Records with step_seq >= from_step_seq, in chain order. 0 returns the whole retained chain (Rust has no default arguments; node’s optional parameter defaults to the same).

Source

fn records_after<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, operation_id: &'life1 str, after_head: Option<&'life2 str>, ) -> Pin<Box<dyn Future<Output = JournalResult<Vec<JournalEntry>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Records strictly after the record whose digest is after_head — the digest-anchored cursor §9.1 names records_after(operation_id, checkpoint_head). None returns everything retained.

Errors with JournalError::Integrity when after_head names no retained record and no pruned anchor.

Source

fn compare_and_install_checkpoint<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, operation_id: &'life1 str, previous_checkpoint_id: Option<&'life2 str>, covered_head: &'life3 str, checkpoint: CheckpointCandidate, ) -> Pin<Box<dyn Future<Output = JournalResult<InstalledCheckpoint>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Atomically install checkpoint iff the operation’s checkpoint pointer is exactly previous_checkpoint_id, and covered_head is the record digest at checkpoint.through_step_seq.

Per §22.14 this deliberately does not require covered_head to still be the current transaction head: transactions appended after the candidate was taken stay as tail.

Errors: JournalError::CasConflict when the checkpoint pointer moved; JournalError::Integrity when covered_head/through_step_seq disagree with the chain, or through_step_seq would move the pointer backwards.

Source

fn latest_checkpoint<'life0, 'life1, 'async_trait>( &'life0 self, operation_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = JournalResult<Option<InstalledCheckpoint>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

The highest-ordinal installed checkpoint, acknowledged or not.

Source

fn ack_checkpoint<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, operation_id: &'life1 str, checkpoint_id: &'life2 str, ) -> Pin<Box<dyn Future<Output = JournalResult<InstalledCheckpoint>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Record the durable acknowledgement that opens the prefix-reclamation boundary. Idempotent.

Errors with JournalError::Integrity when no checkpoint with that id is installed.

Source

fn prune_acked_prefix<'life0, 'life1, 'async_trait>( &'life0 self, operation_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = JournalResult<JournalPruneReceipt>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Reclaim the record prefix covered by the latest acknowledged checkpoint. A no-op while no checkpoint is acknowledged. The pruned boundary is retained as an anchor so Self::head and the next CAS still resolve on a fully-pruned chain (Task 8b correction (d)).

Dyn Compatibility§

This trait is dyn compatible.

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

Implementors§