magnetar/src/util.rs

119 lines
3.0 KiB
Rust

use cached::{Cached, TimedCache};
use std::future::Future;
use std::hash::Hash;
use std::sync::Arc;
use tokio::sync::Mutex;
#[derive(Debug, Clone)]
pub struct SingleTimedAsyncCache<V: Clone + Send + 'static> {
inner: Arc<Mutex<TimedCache<(), V>>>,
}
impl<V: Clone + Send + 'static> SingleTimedAsyncCache<V> {
pub fn with_lifespan(lifespan: u64) -> Self {
Self {
inner: Arc::new(Mutex::new(TimedCache::with_lifespan(lifespan))),
}
}
pub async fn put(&self, val: V) -> Option<V> {
let mut cache = self.inner.lock().await;
cache.cache_set((), val)
}
pub async fn get_opt(&self) -> Option<V> {
let mut cache = self.inner.lock().await;
cache.cache_get(&()).cloned()
}
pub async fn get<E, FT, F>(&self, f: F) -> Result<V, E>
where
FT: Future<Output = Result<V, E>>,
F: FnOnce() -> FT,
{
let mut cache = self.inner.lock().await;
if let Some(val) = cache.cache_get(&()) {
return Ok(val.clone());
}
let val = f().await?;
cache.cache_set((), val.clone());
Ok(val)
}
pub async fn get_sync<E, F>(&self, f: F) -> Result<V, E>
where
F: FnOnce() -> Result<V, E>,
{
let mut cache = self.inner.lock().await;
if let Some(val) = cache.cache_get(&()) {
return Ok(val.clone());
}
let val = f()?;
cache.cache_set((), val.clone());
Ok(val)
}
}
#[derive(Debug, Clone)]
pub struct TimedAsyncCache<K: Clone + Send, V: Clone + Send + 'static> {
inner: Arc<Mutex<TimedCache<K, V>>>,
}
impl<K: Clone + Send + Eq + Hash, V: Clone + Send + 'static> TimedAsyncCache<K, V> {
pub fn with_lifespan(lifespan: u64) -> Self {
Self {
inner: Arc::new(Mutex::new(TimedCache::with_lifespan(lifespan))),
}
}
pub async fn put(&self, key: K, val: V) -> Option<V> {
let mut cache = self.inner.lock().await;
cache.cache_set(key, val)
}
pub async fn remove(&self, key: &K) -> Option<V> {
let mut cache = self.inner.lock().await;
cache.cache_remove(key)
}
pub async fn get_opt(&self, key: &K) -> Option<V> {
let mut cache = self.inner.lock().await;
cache.cache_get(key).cloned()
}
pub async fn get<E, FT, F>(&self, key: K, f: F) -> Result<V, E>
where
FT: Future<Output = Result<V, E>>,
F: FnOnce() -> FT,
{
let mut cache = self.inner.lock().await;
if let Some(val) = cache.cache_get(&key) {
return Ok(val.clone());
}
let val = f().await?;
cache.cache_set(key, val.clone());
Ok(val)
}
pub async fn get_sync<E, F>(&self, key: K, f: F) -> Result<V, E>
where
F: FnOnce() -> Result<V, E>,
{
let mut cache = self.inner.lock().await;
if let Some(val) = cache.cache_get(&key) {
return Ok(val.clone());
}
let val = f()?;
cache.cache_set(key, val.clone());
Ok(val)
}
}