#![cfg_attr(docsrs, feature(doc_cfg))]
pub mod backends;
pub mod builder;
pub mod cache_manager;
pub mod error;
#[cfg(feature = "redis")]
#[cfg_attr(docsrs, doc(cfg(feature = "redis")))]
pub mod invalidation;
#[cfg(feature = "redis")]
#[cfg_attr(docsrs, doc(cfg(feature = "redis")))]
pub mod redis_streams;
pub mod serialization;
pub mod traits;
pub use error::{CacheError, CacheResult};
pub use serialization::{CacheSerializer, JsonSerializer};
pub use std::sync::Arc;
use tracing::{info, warn};
pub use backends::DashMapCache;
#[cfg(feature = "moka")]
#[cfg_attr(docsrs, doc(cfg(feature = "moka")))]
pub use backends::{L1Cache, MokaCache, MokaCacheConfig};
#[cfg(feature = "redis")]
#[cfg_attr(docsrs, doc(cfg(feature = "redis")))]
pub use backends::{L2Cache, RedisCache};
#[cfg(feature = "backend-memcached")]
#[cfg_attr(docsrs, doc(cfg(feature = "backend-memcached")))]
pub use backends::MemcachedCache;
#[cfg(feature = "quick_cache")]
#[cfg_attr(docsrs, doc(cfg(feature = "quick_cache")))]
pub use backends::QuickCacheBackend;
pub use builder::CacheSystemBuilder;
pub use bytes::Bytes;
pub use cache_manager::{
CacheManager,
CacheManagerStats,
CacheStrategy,
CacheTier,
TierConfig,
TierStats,
};
#[cfg(feature = "redis")]
#[cfg_attr(docsrs, doc(cfg(feature = "redis")))]
pub use invalidation::{
InvalidationConfig, InvalidationMessage, InvalidationPublisher, InvalidationStats,
InvalidationSubscriber, ReliableStreamSubscriber,
};
#[cfg(feature = "redis")]
#[cfg_attr(docsrs, doc(cfg(feature = "redis")))]
pub use redis_streams::RedisStreams;
pub use traits::{CacheBackend, L2CacheBackend, StreamingBackend};
#[derive(Clone)]
pub struct CacheSystem {
pub cache_manager: Arc<CacheManager>,
#[cfg(feature = "moka")]
#[cfg_attr(docsrs, doc(cfg(feature = "moka")))]
pub l1_cache: Option<Arc<L1Cache>>,
#[cfg(feature = "redis")]
#[cfg_attr(docsrs, doc(cfg(feature = "redis")))]
pub l2_cache: Option<Arc<L2Cache>>,
}
impl CacheSystem {
#[cfg(all(feature = "moka", feature = "redis"))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "moka", feature = "redis"))))]
pub async fn new() -> CacheResult<Self> {
info!("Initializing Multi-Tier Cache System");
let l1_cache = Arc::new(L1Cache::new(MokaCacheConfig::default())?);
let l2_cache = Arc::new(L2Cache::new().await?);
let cache_manager = Arc::new(CacheManager::new(l1_cache.clone(), l2_cache.clone()).await?);
info!("Multi-Tier Cache System initialized successfully");
Ok(Self {
cache_manager,
l1_cache: Some(l1_cache),
l2_cache: Some(l2_cache),
})
}
#[cfg(all(feature = "moka", feature = "redis"))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "moka", feature = "redis"))))]
pub async fn with_redis_url(redis_url: &str) -> CacheResult<Self> {
info!(redis_url = %redis_url, "Initializing Multi-Tier Cache System with custom Redis URL");
let l1_cache = Arc::new(L1Cache::new(MokaCacheConfig::default())?);
let l2_cache = Arc::new(L2Cache::with_url(redis_url).await?);
let cache_manager =
Arc::new(CacheManager::new(Arc::clone(&l1_cache), Arc::clone(&l2_cache)).await?);
info!("Multi-Tier Cache System initialized successfully");
Ok(Self {
cache_manager,
l1_cache: Some(l1_cache),
l2_cache: Some(l2_cache),
})
}
pub async fn health_check(&self) -> bool {
#[cfg(feature = "moka")]
let l1_ok = match &self.l1_cache {
Some(cache) => {
let backend: &dyn crate::traits::CacheBackend = cache.as_ref();
backend.health_check().await
}
None => true,
};
#[cfg(not(feature = "moka"))]
let l1_ok = true;
#[cfg(feature = "redis")]
let l2_ok = match &self.l2_cache {
Some(cache) => {
let backend: &dyn crate::traits::CacheBackend = cache.as_ref();
backend.health_check().await
}
None => true,
};
#[cfg(not(feature = "redis"))]
let l2_ok = true;
if l1_ok && l2_ok {
info!("Multi-Tier Cache health check passed");
true
} else {
warn!(l1_ok = %l1_ok, l2_ok = %l2_ok, "Multi-Tier Cache health check - partial failure");
l1_ok }
}
#[must_use]
pub fn cache_manager(&self) -> &Arc<CacheManager> {
&self.cache_manager
}
}