Skip to main content

RunLock

Struct RunLock 

Source
pub struct RunLock<Mode = Exclusive> { /* private fields */ }
Expand description

RAII guard holding the run’s flock.

Released on drop. Acquired exclusively (RunLock::acquire) and held across all writes for a single logical mutation, or shared (RunLock::acquire_shared) for the duration of a reader’s multi-file scan so a concurrent reducer cannot leave the reader with a half-updated projection set. A shared guard may hold no lock at all when the run has no .lock file yet — see RunLock::acquire_shared.

The Mode typestate (Exclusive / Shared) records which kind of lock is held: only RunLock<Exclusive> exposes RunLock::witness, so a shared reader can never forge the write capability a LockedRun represents.

Implementations§

Source§

impl RunLock<Exclusive>

Source

pub fn acquire(lock_path: &Path) -> Result<Self>

Acquire the exclusive lock on <run-dir>/.lock, creating the file if needed. Blocks until the lock is available.

Best-effort symlink containment: a .lock that is a symlink is refused (Error::SymlinkStateFile) so flock cannot be taken on a file outside the run tree, which would silently break mutual exclusion. This guards the lock file’s own final component; a symlinked run root is caught downstream when the held critical section opens events.jsonl / the projections (both re-guard the root before writing). See reject_symlink for the check-then-open TOCTOU caveat.

Source

pub fn witness(&self) -> LockedRun<'_>

Mint a LockedRun witness proving this exclusive guard holds the run’s flock. The witness borrows self, so the borrow checker forbids it from outliving the guard (and thus the lock). Use this for the manually-held RunLock::acquire pattern — when the locked body needs control flow (with_lock’s closure cannot express) — then pass &witness to the unlocked append entry points.

Source

pub fn with_lock<R>( paths: &RunPaths, f: impl FnOnce(&LockedRun<'_>) -> Result<R>, ) -> Result<R>

Convenience: run f with the exclusive lock held, passing it a LockedRun witness it can thread into the unlocked append entry points, releasing the lock afterwards.

Source§

impl RunLock<Shared>

Source

pub fn acquire_shared(lock_path: &Path) -> Result<Self>

Acquire a shared (LOCK_SH) lock on an existing <run-dir>/.lock, blocking until no writer holds the exclusive lock. The mirror of RunLock::acquire for the read side: many readers may hold the shared lock at once, but the exclusive lock a reducer takes excludes them all, so a multi-file read taken under this lock never observes the torn state a mid-flight reducer would otherwise expose (design.md §4).

Unlike RunLock::acquire, this never creates the run directory or the lock file — a reader must not bring run-tree state into existence. A missing .lock means no writer has ever locked this run, so a lock-free read is already coherent: the returned guard then holds nothing and drops to a no-op. The same symlink containment as RunLock::acquire applies; the file is opened read-only with O_NOFOLLOW.

Nesting is safe: a shared lock is compatible with other shared locks, so a read path that calls another read helper (each on its own descriptor) cannot deadlock against itself.

Source

pub fn with_shared_lock<T>( lock_path: &Path, f: impl FnOnce() -> Result<T>, ) -> Result<T>

Convenience: run f with the shared lock held, releasing afterwards. The read-side counterpart to RunLock::with_lock — but the closure gets no LockedRun witness: a shared reader has no write capability, so it can never reach a write-side entry point. (It also takes the lock path directly rather than a RunPaths, since a reader may run before the run dir is fully materialized.)

Trait Implementations§

Source§

impl<Mode> Drop for RunLock<Mode>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

§

impl<Mode> Freeze for RunLock<Mode>

§

impl<Mode> RefUnwindSafe for RunLock<Mode>
where Mode: RefUnwindSafe,

§

impl<Mode> Send for RunLock<Mode>
where Mode: Send,

§

impl<Mode> Sync for RunLock<Mode>
where Mode: Sync,

§

impl<Mode> Unpin for RunLock<Mode>
where Mode: Unpin,

§

impl<Mode> UnsafeUnpin for RunLock<Mode>

§

impl<Mode> UnwindSafe for RunLock<Mode>
where Mode: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more