use tokio::sync::{Mutex, RwLock};
use tracing::warn;
pub async fn with_lock<T, F, R>(mutex: &Mutex<T>, f: F) -> R
where
F: FnOnce(&mut T) -> R,
{
let mut guard = mutex.lock().await;
f(&mut guard)
}
pub async fn with_read_lock<T, F, R>(rwlock: &RwLock<T>, f: F) -> R
where
F: FnOnce(&T) -> R,
{
let guard = rwlock.read().await;
f(&guard)
}
pub async fn with_write_lock<T, F, R>(rwlock: &RwLock<T>, f: F) -> R
where
F: FnOnce(&mut T) -> R,
{
let mut guard = rwlock.write().await;
f(&mut guard)
}
pub async fn try_with_lock_timeout<T, F, R>(
mutex: &Mutex<T>,
timeout: std::time::Duration,
f: F,
context: &str,
) -> Option<R>
where
F: FnOnce(&mut T) -> R,
{
use tokio::time::timeout as tokio_timeout;
match tokio_timeout(timeout, mutex.lock()).await {
Ok(mut guard) => Some(f(&mut guard)),
Err(_) => {
warn!("{}: Failed to acquire lock within {:?}", context, timeout);
None
}
}
}