pub struct FileLock { /* private fields */ }Expand description
File locking mechanism with process ID tracking
Provides exclusive access to files by creating lock files that contain the process ID of the lock holder. This prevents race conditions when multiple processes attempt to access the same file concurrently.
§Lock Files
Lock files are named {file}.lock and contain the process ID as text.
Example: ./data/my-env/state.json.lock contains “12345”
§Stale Lock Detection
If a process crashes while holding a lock, the lock file remains but the process is dead. This implementation detects stale locks by checking if the process ID in the lock file is still running, then automatically cleans up and retries.
§RAII Pattern
The lock is automatically released when the FileLock is dropped, ensuring
cleanup even if an error occurs during file operations.
Implementations§
Source§impl FileLock
impl FileLock
Sourcepub fn acquire(
file_path: &Path,
timeout: Duration,
) -> Result<Self, FileLockError>
pub fn acquire( file_path: &Path, timeout: Duration, ) -> Result<Self, FileLockError>
Attempt to acquire a lock for the given file path
Creates a lock file at {file_path}.lock containing the current process ID.
If the lock file already exists, checks if the holding process is still alive.
If the process is dead, removes the stale lock and retries.
§Arguments
file_path- Path to the file to lock (the actual file, not the lock file)timeout- Maximum time to wait for lock acquisition
§Returns
Returns FileLock on successful acquisition, which will automatically release
the lock when dropped.
§Errors
Returns error if:
- Another process holds the lock and timeout expires (
AcquisitionTimeout) - Lock file cannot be created due to permissions (
CreateFailed) - I/O error occurs during lock operations
§Examples
use std::path::Path;
use std::time::Duration;
use torrust_tracker_deployer_lib::infrastructure::persistence::filesystem::file_lock::FileLock;
let file_path = Path::new("./data/test/state.json");
let timeout = Duration::from_secs(10);
match FileLock::acquire(file_path, timeout) {
Ok(lock) => {
// Perform operations on the file
// Lock automatically released when lock goes out of scope
}
Err(e) => eprintln!("Failed to acquire lock: {}", e),
}Sourcepub fn release(self) -> Result<(), FileLockError>
pub fn release(self) -> Result<(), FileLockError>
Release the lock by removing the lock file
This is called automatically when the FileLock is dropped, but can
also be called explicitly for better error handling.
§Errors
Returns error if the lock file cannot be removed due to I/O issues.
§Examples
use std::path::Path;
use std::time::Duration;
use torrust_tracker_deployer_lib::infrastructure::persistence::filesystem::file_lock::FileLock;
let lock = FileLock::acquire(Path::new("test.json"), Duration::from_secs(5))?;
// ... perform operations ...
lock.release()?; // Explicit release with error handlingTrait Implementations§
Auto Trait Implementations§
impl Freeze for FileLock
impl RefUnwindSafe for FileLock
impl Send for FileLock
impl Sync for FileLock
impl Unpin for FileLock
impl UnsafeUnpin for FileLock
impl UnwindSafe for FileLock
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 moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request