use crate::cache::manager::CacheManager;
use crate::error::Result; use crate::options::MemoryCacheOptions; use async_trait::async_trait;
use moka::future::Cache;
use std::time::Duration;
#[derive(Clone)] pub struct MemoryCacheManager {
cache: Cache<String, String, ahash::RandomState>,
options: MemoryCacheOptions,
prefix: String,
}
impl MemoryCacheManager {
pub fn new(prefix: String, options: MemoryCacheOptions) -> Self {
let cache_builder = Cache::builder()
.max_capacity(options.max_capacity)
.name(format!("sockudo-memory-cache-{}", prefix).as_str());
let cache = if options.ttl > 0 {
cache_builder.time_to_live(Duration::from_secs(options.ttl))
} else {
cache_builder
}
.build_with_hasher(ahash::RandomState::new());
Self {
cache,
options,
prefix,
}
}
fn prefixed_key(&self, key: &str) -> String {
format!("{}:{}", self.prefix, key)
}
}
#[async_trait]
impl CacheManager for MemoryCacheManager {
async fn has(&mut self, key: &str) -> Result<bool> {
let prefixed_key = self.prefixed_key(key);
let exists = self.cache.get(&prefixed_key).await.is_some();
Ok(exists)
}
async fn get(&mut self, key: &str) -> Result<Option<String>> {
let prefixed_key = self.prefixed_key(key);
Ok(self.cache.get(&prefixed_key).await)
}
async fn set(&mut self, key: &str, value: &str, _ttl_seconds: u64) -> Result<()> {
let prefixed_key = self.prefixed_key(key);
let value_string = value.to_string();
self.cache.insert(prefixed_key, value_string).await;
Ok(())
}
async fn remove(&mut self, key: &str) -> Result<()> {
let prefixed_key = self.prefixed_key(key);
self.cache.invalidate(&prefixed_key).await;
Ok(())
}
async fn disconnect(&mut self) -> Result<()> {
self.cache.invalidate_all();
Ok(())
}
async fn ttl(&mut self, key: &str) -> Result<Option<Duration>> {
let prefixed_key = self.prefixed_key(key);
if self.cache.contains_key(&prefixed_key) {
if self.options.ttl > 0 {
Ok(Some(Duration::from_secs(self.options.ttl)))
} else {
Ok(None)
}
} else {
Ok(None) }
}
}
impl MemoryCacheManager {
pub async fn delete(&mut self, key: &str) -> Result<bool> {
let prefixed_key = self.prefixed_key(key);
if self.cache.contains_key(&prefixed_key) {
self.cache.invalidate(&prefixed_key).await;
Ok(true)
} else {
Ok(false)
}
}
pub async fn get_many(&mut self, keys: &[&str]) -> Result<Vec<Option<String>>> {
let mut results = Vec::with_capacity(keys.len());
for &key in keys {
results.push(self.get(key).await?);
}
Ok(results)
}
pub async fn set_many(&mut self, pairs: &[(&str, &str)], _ttl_seconds: u64) -> Result<()> {
for (key, value) in pairs {
let prefixed_key = self.prefixed_key(key);
let value_string = value.to_string();
self.cache.insert(prefixed_key, value_string).await;
}
Ok(())
}
}