pub struct SessionEventLog { /* private fields */ }Expand description
Append-only JSONL log for one conversation-session’s events.jsonl.
§Examples
use tempfile::tempdir;
use zeph_session::event::SessionEvent;
use zeph_session::log::SessionEventLog;
let dir = tempdir().unwrap();
let log = SessionEventLog::open(dir.path()).await.unwrap();
log.append(None, None, SessionEvent::SessionEnded { reason: "user_quit".to_owned() })
.await
.unwrap();
assert_eq!(log.last_seq(), Some(0));Implementations§
Source§impl SessionEventLog
impl SessionEventLog
Sourcepub async fn open(session_dir: &Path) -> Result<Self, SessionError>
pub async fn open(session_dir: &Path) -> Result<Self, SessionError>
Open (creating if absent) the events.jsonl log under session_dir.
Validates the existing file per INV-SP-2, dropping a torn trailing line from the
in-memory result, then opens the file in append mode for subsequent writes. Sets
file/directory permissions to 0o700/0o600 on Unix (spec §4.1); a no-op on other
platforms.
Does not take the cross-process advisory lock, and never physically truncates the file
(even if a torn tail is found) — safe for read-only tooling that may run alongside a live
writer whose in-flight, not-yet-fsynced line could otherwise be mistaken for “torn” and
destroyed (#5487 Finding B). The session’s owning actor/agent process should use
Self::open_exclusive instead, which does perform the physical repair.
§Errors
Returns SessionError::Io if the directory or file cannot be created, or
SessionError::Serde surfaces only via Self::read_all, never here (torn lines are
discarded, not treated as fatal).
Sourcepub async fn open_exclusive(session_dir: &Path) -> Result<Self, SessionError>
pub async fn open_exclusive(session_dir: &Path) -> Result<Self, SessionError>
Open the events.jsonl log under session_dir like Self::open, but additionally
take a non-blocking, exclusive advisory lock (flock(2) on Unix, mirroring
zeph-scheduler’s PidFile) enforcing INV-D2’s single-writer invariant.
Intended for the session’s owning actor/agent process. On non-Unix targets the lock
is a no-op (the workspace has no vetted cross-platform advisory-locking primitive), so
this degrades to Self::open’s behavior there.
§Errors
Returns SessionError::AlreadyLocked if another process already holds the session’s
write lock, or any error Self::open can return.
Sourcepub fn last_seq(&self) -> Option<u64>
pub fn last_seq(&self) -> Option<u64>
The highest seq durably appended so far, or None if the log is empty.
Sourcepub async fn append(
&self,
turn_id: Option<u64>,
parent_seq: Option<u64>,
kind: SessionEvent,
) -> Result<SessionEventEnvelope, SessionError>
pub async fn append( &self, turn_id: Option<u64>, parent_seq: Option<u64>, kind: SessionEvent, ) -> Result<SessionEventEnvelope, SessionError>
Append one event, assigning it the next monotonic seq, and fsync before returning.
The single write_all + sync_all pair is the atomicity boundary INV-SP-2 relies on: a
crash mid-write can only ever corrupt this one trailing line.
§Errors
Returns SessionError::Serde if the event cannot be JSON-encoded, or
SessionError::Io if the write or fsync fails.
Sourcepub async fn read_all(&self) -> Result<Vec<SessionEventEnvelope>, SessionError>
pub async fn read_all(&self) -> Result<Vec<SessionEventEnvelope>, SessionError>
Read and validate every event currently in the log, dropping a torn trailing line from
the result (INV-SP-2). Only physically repairs the file if this handle was opened via
Self::open_exclusive — see that method’s doc comment.
§Errors
Returns SessionError::Io if the file cannot be read.
Auto Trait Implementations§
impl !Freeze for SessionEventLog
impl !RefUnwindSafe for SessionEventLog
impl !UnwindSafe for SessionEventLog
impl Send for SessionEventLog
impl Sync for SessionEventLog
impl Unpin for SessionEventLog
impl UnsafeUnpin for SessionEventLog
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
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