pub struct EventLog<E>where
E: Context + BufferPooler,{ /* private fields */ }Expand description
An append-only, ordered log of conversation Events.
Generic over a commonware_storage::Context so the same code runs on the
tokio backend in production and the deterministic backend in tests. See the
crate-level docs for the ordering contract and runtime-coexistence notes.
Implementations§
Source§impl<E> EventLog<E>where
E: Context + BufferPooler,
impl<E> EventLog<E>where
E: Context + BufferPooler,
Sourcepub async fn open(
context: E,
config: EventLogConfig,
) -> Result<Self, EventLogError>
pub async fn open( context: E, config: EventLogConfig, ) -> Result<Self, EventLogError>
Open (creating if absent, recovering if present) the event log for a
conversation on the given runtime context.
On open the journal replays only its final section to recover the exact append size, and self-heals any data/offset divergence left by a crash.
§Errors
Returns EventLogError::Journal if the underlying storage fails to
initialize or recover the journal.
Sourcepub async fn destroy(self) -> Result<(), EventLogError>
pub async fn destroy(self) -> Result<(), EventLogError>
Destroy the log: consume the handle and REMOVE the partition’s
underlying blobs (data + offsets) from storage. The erasure primitive
(#216): after this, a fresh EventLog::open of the same partition
starts empty.
Deliberately consuming — a destroyed log has no valid further operation, and the caller must drop every other handle first (the control plane’s host serializes this through its single command loop and evicts its cache entry before destroying).
§Errors
Returns EventLogError::Journal if the underlying blob removal
fails.
Sourcepub async fn append(&self, event: &Event) -> Result<u64, EventLogError>
pub async fn append(&self, event: &Event) -> Result<u64, EventLogError>
Append a single event, returning the position the journal assigned it.
Positions are strictly increasing from 0 and define replay order. The
caller must append in conversation order (turn, then seq within a turn)
for replay to reflect that order.
Takes &self: EventLog’s own lock (see the struct-level doc)
recovers a shared reference over the journal’s &mut self ops.
Appends are buffered for durability; call EventLog::commit (or
EventLog::sync) to guarantee they survive a crash.
§Errors
Returns EventLogError::Journal if the item cannot be encoded or the
underlying storage write fails.
Sourcepub async fn len(&self) -> u64
pub async fn len(&self) -> u64
Number of events appended to the log (the position the next append will receive). Not reduced by pruning.
Sourcepub async fn replay_with_positions(
&self,
) -> Result<Vec<(u64, Event)>, EventLogError>
pub async fn replay_with_positions( &self, ) -> Result<Vec<(u64, Event)>, EventLogError>
Replay every event in append order, each paired with its position.
The returned Vec is ordered by position ascending (0, 1, 2, …),
which is conversation order. Each tuple is (position, event).
This collects the full log into memory; it is intended for rebuilding
in-memory conversation state on resume. For very large logs a streaming
variant could be added later (the journal exposes a Stream), but the
foundational API materializes for simplicity.
§Errors
Returns EventLogError::Journal if the journal cannot start the replay
stream or if decoding any stored event fails.
Sourcepub async fn replay_from_with_positions(
&self,
start: u64,
) -> Result<Vec<(u64, Event)>, EventLogError>
pub async fn replay_from_with_positions( &self, start: u64, ) -> Result<Vec<(u64, Event)>, EventLogError>
Replay events in append order starting at position start, each paired
with its position.
The journal is position-indexed, so resuming at an offset is cheap — the
reader seeks to start rather than scanning from zero. This is what lets
a caller replay only the tail since a durable checkpoint instead of
re-reading the whole partition every time. start is clamped up to the
pruning boundary, and a start at or past the end yields an empty Vec.
Returned tuples are (position, event) for positions in
[max(start, bounds.start), len), ascending.
§Errors
Returns EventLogError::Journal if the journal cannot start the replay
stream or if decoding any stored event fails.
Sourcepub async fn replay(&self) -> Result<Vec<Event>, EventLogError>
pub async fn replay(&self) -> Result<Vec<Event>, EventLogError>
Replay every event in append order, discarding positions.
Convenience over EventLog::replay_with_positions for callers that
only need the ordered events.
§Errors
Returns EventLogError::Journal on the same conditions as
EventLog::replay_with_positions.
Sourcepub async fn replay_from(&self, start: u64) -> Result<Vec<Event>, EventLogError>
pub async fn replay_from(&self, start: u64) -> Result<Vec<Event>, EventLogError>
Replay events from position start in append order, discarding
positions. Convenience over EventLog::replay_from_with_positions.
§Errors
Returns EventLogError::Journal on the same conditions as
EventLog::replay_from_with_positions.
Sourcepub async fn replay_quarantining(
&self,
) -> Result<(Vec<(u64, Event)>, Vec<QuarantinedItem>), EventLogError>
pub async fn replay_quarantining( &self, ) -> Result<(Vec<(u64, Event)>, Vec<QuarantinedItem>), EventLogError>
Replay every event in append order, skipping any position whose item cannot be decoded rather than aborting the whole replay.
EventLog::replay_with_positions stops at the first bad item (the
backup/DR gap #799 tracks: one corrupted event permanently locks a
conversation out of replay). This reads each position independently
through the journal’s position index — a corrupted item’s neighbors
don’t depend on decoding it — so it recovers everything readable and
reports the rest as QuarantinedItems. This is the primitive a
conversation repair operation uses to drop only the unreadable
event(s) and let the rest of the log replay again; it is otherwise
intended for that recovery path, not routine replay (one read per
position, versus one streamed pass).
§Errors
Returns EventLogError::Journal if the journal cannot report its
own bounds. A per-item decode failure is reported in the returned
quarantine list, never as an Err.
Sourcepub async fn commit(&self) -> Result<(), EventLogError>
pub async fn commit(&self) -> Result<(), EventLogError>
Durably persist all buffered appends, guaranteeing they survive a crash.
Committed appends survive a crash, but the next EventLog::open may
perform recovery work rebuilding the position index from data before
replay is available — EventLog::sync additionally makes the next
open recovery-free.
§Errors
Returns EventLogError::Journal if the underlying flush fails.
Sourcepub async fn sync(&self) -> Result<(), EventLogError>
pub async fn sync(&self) -> Result<(), EventLogError>
Stronger durability than EventLog::commit: persist and guarantee no
recovery work is needed on next open.
§Errors
Returns EventLogError::Journal if the underlying sync fails.
Auto Trait Implementations§
impl<E> !Freeze for EventLog<E>
impl<E> !RefUnwindSafe for EventLog<E>
impl<E> !UnwindSafe for EventLog<E>
impl<E> Send for EventLog<E>
impl<E> Sync for EventLog<E>
impl<E> Unpin for EventLog<E>
impl<E> UnsafeUnpin for EventLog<E>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
Source§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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