Skip to main content

ConfigLock

Struct ConfigLock 

Source
pub struct ConfigLock { /* private fields */ }
Expand description

An exclusive advisory lock over one config file, held for as long as the value lives and released when it drops (including on an early ?, and by the kernel if the process dies holding it).

Keyed on the path it is given rather than on shep.toml specifically: shep-cli’s ShepToml::edit takes one over shep.toml, and commands::dog_migration takes one over dogs.toml, which has two writers of its own. Whenever both are held at once, shep.toml’s is taken first, which is the whole of what keeps the two orderings from deadlocking; migrate_dog_sections is the one caller that holds both, and it says so at the point it nests them.

The lock is on a sibling <name>.lock, never on the config itself, and that is the whole design decision, the same one barks::RingLock records: ShepToml::save finishes by renameing a new file over the config, which replaces the inode. A lock taken on the config would be a lock on an inode the very next successful save unlinks; the next writer would open the new inode, find it unlocked, and the two would be excluding nothing. The lock file is never renamed, never rewritten and never read; it exists only to be an inode with a stable identity, and it is left on disk between edits on purpose so both writers keep agreeing on which one it is.

Derives Debug rather than opting out: the fields are a held OS lock handle (a flock(2) wrapper on unix, a bare File on Windows), never a secret, so there is nothing here for a redacted impl to protect.

Implementations§

Source§

impl ConfigLock

Source

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

Blocks until this process holds path’s lock exclusively.

§Errors

The lock file could not be created beside path, or flock failed for a reason other than contention (contention blocks rather than failing).

Trait Implementations§

Source§

impl Debug for ConfigLock

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.