warpdrive_proxy/cache/mod.rs
1//! Cache abstraction layer for WarpDrive
2//!
3//! This module provides a common trait for cache backends, enabling
4//! pluggable cache implementations (Redis, in-memory LRU, etc.).
5//!
6//! The design follows zero-cost abstraction principles:
7//! - Async-first with tokio
8//! - Binary-safe (Vec<u8>) to support any serialization format
9//! - Generic error handling with anyhow
10//! - Minimal allocations in hot paths
11//!
12//! # Example
13//!
14//! ```no_run
15//! use warpdrive::cache::{Cache, redis::RedisCache};
16//!
17//! # async fn example() -> anyhow::Result<()> {
18//! let cache = RedisCache::from_url(
19//! "redis://localhost:6379",
20//! "warpdrive:cache:".to_string()
21//! ).await?;
22//!
23//! // Store data with 60 second TTL
24//! cache.set("user:123", b"user_data", 60).await?;
25//!
26//! // Retrieve data
27//! if let Some(data) = cache.get("user:123").await? {
28//! println!("Found {} bytes", data.len());
29//! }
30//! # Ok(())
31//! # }
32//! ```
33
34use async_trait::async_trait;
35
36/// Common cache trait for all backend implementations
37///
38/// This trait defines the minimal interface required for a cache backend.
39/// All operations are async and return `anyhow::Result` for flexible error handling.
40///
41/// # Binary Safety
42///
43/// The trait uses `Vec<u8>` for values to support any serialization format
44/// (JSON, MessagePack, Protocol Buffers, etc.). This keeps the cache layer
45/// agnostic to the data format.
46///
47/// # TTL Behavior
48///
49/// All cache entries must support time-to-live (TTL) expiration. A TTL of 0
50/// should be treated as "use backend default" or "no expiration" depending
51/// on the implementation.
52#[async_trait]
53pub trait Cache: Send + Sync {
54 /// Retrieve a value from cache by key
55 ///
56 /// Returns `Ok(Some(value))` if found, `Ok(None)` if not found or expired,
57 /// or `Err` on connection/IO errors.
58 async fn get(&self, key: &str) -> anyhow::Result<Option<Vec<u8>>>;
59
60 /// Store a value in cache with TTL
61 ///
62 /// # Parameters
63 ///
64 /// - `key`: Cache key (will be prefixed by implementation)
65 /// - `value`: Binary data to store
66 /// - `ttl_seconds`: Time-to-live in seconds (0 = backend default)
67 async fn set(&self, key: &str, value: &[u8], ttl_seconds: u64) -> anyhow::Result<()>;
68
69 /// Delete a value from cache
70 ///
71 /// Returns `Ok(())` regardless of whether the key existed.
72 async fn delete(&self, key: &str) -> anyhow::Result<()>;
73
74 /// Check if a key exists in cache
75 ///
76 /// Returns `true` if the key exists and has not expired.
77 async fn exists(&self, key: &str) -> anyhow::Result<bool>;
78}
79
80pub mod coordinator;
81pub mod invalidation;
82pub mod memory;
83pub mod redis;