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_headagainstthrough_step_seqbut 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§
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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).
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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,
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".