diff options
Diffstat (limited to 'crates/common/flockfile/src/unix.rs')
-rw-r--r-- | crates/common/flockfile/src/unix.rs | 70 |
1 files changed, 38 insertions, 32 deletions
diff --git a/crates/common/flockfile/src/unix.rs b/crates/common/flockfile/src/unix.rs index 28646601..72fe1260 100644 --- a/crates/common/flockfile/src/unix.rs +++ b/crates/common/flockfile/src/unix.rs @@ -5,7 +5,9 @@ use std::{ os::unix::io::AsRawFd, path::{Path, PathBuf}, }; -use tracing::{debug, error, warn}; +use tracing::{debug, error, info, warn}; + +const LOCK_CHILD_DIRECTORY: &str = "lock/"; #[derive(thiserror::Error, Debug)] pub enum FlockfileError { @@ -24,6 +26,15 @@ pub enum FlockfileError { }, } +impl FlockfileError { + fn path(&self) -> &Path { + match self { + FlockfileError::FromIo { path, .. } => path, + FlockfileError::FromNix { path, .. } => path, + } + } +} + /// flockfile creates a lockfile in the filesystem under `/run/lock` and then creates a filelock using system fcntl with flock. /// flockfile will automatically remove lockfile on application exit and the OS should cleanup the filelock afterwards. /// If application exits unexpectedly the filelock will be dropped, but the lockfile will not be removed unless handled in signal handler. @@ -40,29 +51,26 @@ impl Flockfile { /// /// let _lockfile = match flockfile::Flockfile::new_lock("app")).unwrap(); /// - pub fn new_lock(lock_name: impl AsRef<Path>) -> Result<Flockfile, FlockfileError> { - let path = Path::new("/run/lock").join(lock_name); - - let file = match OpenOptions::new() + pub fn new_lock(path: impl AsRef<Path>) -> Result<Flockfile, FlockfileError> { + let path = PathBuf::new().join(path); + let file = OpenOptions::new() .create(true) .read(true) .write(true) .open(&path) - { - Ok(file) => file, - Err(err) => { - return Err(FlockfileError::FromIo { path, source: err }); - } - }; - - let () = match flock(file.as_raw_fd(), FlockArg::LockExclusiveNonblock) { - Ok(()) => (), - Err(err) => { - return Err(FlockfileError::FromNix { path, source: err }); + .map_err(|err| FlockfileError::FromIo { + path: path.clone(), + source: err, + })?; + + flock(file.as_raw_fd(), FlockArg::LockExclusiveNonblock).map_err(|err| { + FlockfileError::FromNix { + path: path.clone(), + source: err, } - }; + })?; - debug!(r#"Lockfile created "{:?}""#, &path); + info!(r#"Lockfile created {:?}"#, &path); Ok(Flockfile { handle: Some(file), path, @@ -104,20 +112,18 @@ impl AsRef<Path> for Flockfile { } } -/// Check /run/lock/ for a lock file of a given `app_name` -pub fn check_another_instance_is_not_running(app_name: &str) -> Result<Flockfile, FlockfileError> { - match Flockfile::new_lock(format!("{}.lock", app_name)) { - Ok(file) => Ok(file), - Err(err) => { - return match &err { - FlockfileError::FromIo { path, .. } | FlockfileError::FromNix { path, .. } => { - error!("Another instance of {} is running.", app_name); - error!("Lock file path: {}", path.as_path().to_str().unwrap()); - Err(err) - } - } - } - } +/// Check `run_dir`/lock/ for a lock file of a given `app_name` +pub fn check_another_instance_is_not_running( + app_name: &str, + run_dir: &Path, +) -> Result<Flockfile, FlockfileError> { + let lock_path = run_dir.join(format!("{}{}.lock", LOCK_CHILD_DIRECTORY, app_name)); + + Flockfile::new_lock(lock_path.as_path()).map_err(|err| { + error!("Another instance of {} is running.", app_name); + error!("Lock file path: {}", err.path().to_str().unwrap()); + err + }) } #[cfg(test)] |