use crate::Result;
use fs4::fs_std::FileExt;
use ohno::IntoAppError;
use std::fs::{File, OpenOptions};
use std::path::Path;
const LOG_TARGET: &str = " collector";
#[derive(Debug)]
pub struct CacheLockGuard(File);
impl Drop for CacheLockGuard {
fn drop(&mut self) {
if let Err(e) = self.0.unlock() {
log::warn!(target: LOG_TARGET, "Could not unlock cache: {e:#}");
}
}
}
pub async fn acquire_cache_lock(cache_dir: &Path) -> Result<CacheLockGuard> {
let lock_path = cache_dir.join("cache.lock");
let file = OpenOptions::new()
.write(true)
.create(true)
.truncate(false)
.open(&lock_path)
.into_app_err_with(|| format!("Could not open cache lock file at '{}'", lock_path.display()))?;
let file = tokio::task::spawn_blocking(move || {
file.lock_exclusive()
.into_app_err_with(|| format!("Could not acquire exclusive lock on cache at '{}'", lock_path.display()))?;
log::debug!(target: LOG_TARGET, "Acquired cache lock at '{}'", lock_path.display());
Ok::<_, ohno::AppError>(file)
})
.await
.into_app_err("Lock task panicked")??;
Ok(CacheLockGuard(file))
}