pub struct HostLock { /* private fields */ }Expand description
A held lock. Releasing it is dropping it.
There is no release() returning a Result, deliberately: releasing is
closing a file descriptor, the kernel does it whether this program asks or
not, and an API that suggested release could fail would invite a caller to
handle a failure that does not exist.
Implementations§
Source§impl HostLock
impl HostLock
Sourcepub fn try_acquire(paths: &AppPaths, kind: LockKind) -> Result<Self, LockError>
pub fn try_acquire(paths: &AppPaths, kind: LockKind) -> Result<Self, LockError>
Takes the lock, or reports who has it, without waiting.
§Errors
LockError::Held when another process has it, LockError::Io when
the lock file cannot be opened, and LockError::Identity when this
process cannot describe itself.
Sourcepub fn acquire(
paths: &AppPaths,
kind: LockKind,
wait: Duration,
) -> Result<Self, LockError>
pub fn acquire( paths: &AppPaths, kind: LockKind, wait: Duration, ) -> Result<Self, LockError>
Takes the lock, retrying until wait elapses.
e1 takes the allocation lock before each runtime it creates, and brief
contention there is expected rather than exceptional, so waiting a
little is the right default for that caller. The single-instance lock
should normally use HostLock::try_acquire: a second agent is a
configuration problem, and waiting for it makes the problem quieter
rather than fixing it.
§This blocks the calling thread
The retry loop is std::thread::sleep, not a timer an executor can
park. e1 takes the allocation lock from inside async reconciliation,
and calling this directly from a tokio task blocks a worker thread for
up to wait — starving every other task scheduled on it, and with a
current-thread runtime deadlocking against the very task that would
release the lock. Async callers must wrap it in
tokio::task::spawn_blocking, which is also where the returned
HostLock should then live, since dropping it is the release.
HostLock::try_acquire does not block and is safe to call inline.
§Errors
As HostLock::try_acquire, reporting the last holder seen.
Sourcepub fn holder_of(path: &Path) -> Result<Option<LockHolder>, LockError>
pub fn holder_of(path: &Path) -> Result<Option<LockHolder>, LockError>
Reads the holder record of a lock without trying to take it.
Answers Ok(None) when the file does not exist or carries no readable
record. It deliberately says nothing about whether the lock is held:
the record outlives its writer by design, and the only authority on
whether a lock is free is trying to take it.
§Errors
LockError::Io when the file exists but cannot be read.
Sourcepub fn recorded_holder_is_live(path: &Path) -> Result<bool, LockError>
pub fn recorded_holder_is_live(path: &Path) -> Result<bool, LockError>
Whether the recorded holder of path is still running.
For diagnostics — host show reporting a lock whose record names a
process that no longer exists tells an operator something a bare
“locked/unlocked” does not.
§Errors
LockError::Io when the record cannot be read.