use std::time::Duration;
pub trait CacheMetrics: Send + Sync {
fn record_hit(&self, key: &str, duration: Duration) {
debug!("Cache HIT: {} took {:?}", key, duration);
}
fn record_miss(&self, key: &str, duration: Duration) {
debug!("Cache MISS: {} took {:?}", key, duration);
}
fn record_set(&self, key: &str, duration: Duration) {
debug!("Cache SET: {} took {:?}", key, duration);
}
fn record_delete(&self, key: &str, duration: Duration) {
debug!("Cache DELETE: {} took {:?}", key, duration);
}
fn record_error(&self, key: &str, error: &str) {
warn!("Cache ERROR for {}: {}", key, error);
}
}
#[derive(Clone, Default)]
pub struct NoOpMetrics;
impl CacheMetrics for NoOpMetrics {
fn record_hit(&self, _key: &str, _duration: Duration) {}
fn record_miss(&self, _key: &str, _duration: Duration) {}
fn record_set(&self, _key: &str, _duration: Duration) {}
fn record_delete(&self, _key: &str, _duration: Duration) {}
fn record_error(&self, _key: &str, _error: &str) {}
}
#[derive(Clone, Debug, Default)]
pub enum TtlPolicy {
#[default]
Default,
Fixed(Duration),
Infinite,
PerType(fn(&str) -> Duration),
}
impl TtlPolicy {
pub fn get_ttl(&self, entity_type: &str) -> Option<Duration> {
match self {
TtlPolicy::Default => None,
TtlPolicy::Fixed(d) => Some(*d),
TtlPolicy::Infinite => None,
TtlPolicy::PerType(f) => Some(f(entity_type)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_noop_metrics() {
let metrics = NoOpMetrics;
metrics.record_hit("key", Duration::from_secs(1));
metrics.record_miss("key", Duration::from_secs(2));
}
#[test]
fn test_ttl_policy_default() {
let policy = TtlPolicy::Default;
assert_eq!(policy.get_ttl("any"), None);
}
#[test]
fn test_ttl_policy_fixed() {
let policy = TtlPolicy::Fixed(Duration::from_secs(300));
assert_eq!(policy.get_ttl("any"), Some(Duration::from_secs(300)));
}
#[test]
fn test_ttl_policy_per_type() {
let policy = TtlPolicy::PerType(|entity_type| match entity_type {
"employment" => Duration::from_secs(3600),
_ => Duration::from_secs(1800),
});
assert_eq!(
policy.get_ttl("employment"),
Some(Duration::from_secs(3600))
);
assert_eq!(policy.get_ttl("other"), Some(Duration::from_secs(1800)));
}
}