use std::fmt::Display;
use std::sync::Arc;
use std::time::Duration;
use crate::cache::Cache;
use serde::{Serialize, de::DeserializeOwned};
use crate::cache_store::TypedCache;
pub use wacore::store::cache::CacheStore;
#[derive(Debug, Clone)]
pub struct CacheEntryConfig {
pub timeout: Option<Duration>,
pub capacity: u64,
}
impl CacheEntryConfig {
pub fn new(timeout: Option<Duration>, capacity: u64) -> Self {
Self { timeout, capacity }
}
pub(crate) fn build_with_ttl<K, V>(&self) -> Cache<K, V>
where
K: std::hash::Hash + Eq + Clone + Send + Sync + 'static,
V: Clone + Send + Sync + 'static,
{
let mut builder = Cache::builder().max_capacity(self.capacity);
if let Some(timeout) = self.timeout {
builder = builder.time_to_live(timeout);
}
builder.build()
}
pub(crate) fn build_typed_ttl<K, V>(
&self,
store: Option<Arc<dyn CacheStore>>,
namespace: &'static str,
) -> TypedCache<K, V>
where
K: std::hash::Hash + Eq + Clone + Display + Send + Sync + 'static,
V: Clone + Serialize + DeserializeOwned + Send + Sync + 'static,
{
match store {
Some(s) => TypedCache::from_store(s, namespace, self.timeout),
None => TypedCache::from_moka(self.build_with_ttl()),
}
}
pub(crate) fn build_with_tti<K, V>(&self) -> Cache<K, V>
where
K: std::hash::Hash + Eq + Clone + Send + Sync + 'static,
V: Clone + Send + Sync + 'static,
{
let mut builder = Cache::builder().max_capacity(self.capacity);
if let Some(timeout) = self.timeout {
builder = builder.time_to_idle(timeout);
}
builder.build()
}
}
#[derive(Default, Clone)]
pub struct CacheStores {
pub group_cache: Option<Arc<dyn CacheStore>>,
pub device_cache: Option<Arc<dyn CacheStore>>,
pub device_registry_cache: Option<Arc<dyn CacheStore>>,
pub lid_pn_cache: Option<Arc<dyn CacheStore>>,
}
impl CacheStores {
pub fn all(store: Arc<dyn CacheStore>) -> Self {
Self {
group_cache: Some(store.clone()),
device_cache: Some(store.clone()),
device_registry_cache: Some(store.clone()),
lid_pn_cache: Some(store),
}
}
}
#[derive(Clone)]
pub struct CacheConfig {
pub group_cache: CacheEntryConfig,
pub device_cache: CacheEntryConfig,
pub device_registry_cache: CacheEntryConfig,
pub lid_pn_cache: CacheEntryConfig,
pub retried_group_messages: CacheEntryConfig,
pub recent_messages: CacheEntryConfig,
pub message_retry_counts: CacheEntryConfig,
pub pdo_pending_requests: CacheEntryConfig,
pub session_locks_capacity: u64,
pub message_queues_capacity: u64,
pub message_enqueue_locks_capacity: u64,
pub sent_message_ttl_secs: u64,
pub cache_stores: CacheStores,
}
impl std::fmt::Debug for CacheConfig {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("CacheConfig")
.field("group_cache", &self.group_cache)
.field("device_cache", &self.device_cache)
.field("device_registry_cache", &self.device_registry_cache)
.field("lid_pn_cache", &self.lid_pn_cache)
.field("retried_group_messages", &self.retried_group_messages)
.field("recent_messages", &self.recent_messages)
.field("message_retry_counts", &self.message_retry_counts)
.field("pdo_pending_requests", &self.pdo_pending_requests)
.field("session_locks_capacity", &self.session_locks_capacity)
.field("message_queues_capacity", &self.message_queues_capacity)
.field(
"message_enqueue_locks_capacity",
&self.message_enqueue_locks_capacity,
)
.field("sent_message_ttl_secs", &self.sent_message_ttl_secs)
.field(
"cache_stores.group_cache",
&self.cache_stores.group_cache.is_some(),
)
.field(
"cache_stores.device_cache",
&self.cache_stores.device_cache.is_some(),
)
.field(
"cache_stores.device_registry_cache",
&self.cache_stores.device_registry_cache.is_some(),
)
.field(
"cache_stores.lid_pn_cache",
&self.cache_stores.lid_pn_cache.is_some(),
)
.finish()
}
}
impl Default for CacheConfig {
fn default() -> Self {
let one_hour = Some(Duration::from_secs(3600));
let five_min = Some(Duration::from_secs(300));
Self {
group_cache: CacheEntryConfig::new(one_hour, 250),
device_cache: CacheEntryConfig::new(one_hour, 5_000),
device_registry_cache: CacheEntryConfig::new(one_hour, 5_000),
lid_pn_cache: CacheEntryConfig::new(one_hour, 10_000),
retried_group_messages: CacheEntryConfig::new(five_min, 2_000),
recent_messages: CacheEntryConfig::new(five_min, 0),
message_retry_counts: CacheEntryConfig::new(five_min, 1_000),
pdo_pending_requests: CacheEntryConfig::new(Some(Duration::from_secs(30)), 500),
session_locks_capacity: 2_000,
message_queues_capacity: 2_000,
message_enqueue_locks_capacity: 2_000,
sent_message_ttl_secs: 300,
cache_stores: CacheStores::default(),
}
}
}