litellm_rs/core/traits/
cache.rs1use async_trait::async_trait;
6use serde::{Deserialize, Serialize};
7use std::time::Duration;
8
9#[async_trait]
13pub trait Cache<K, V>: Send + Sync
14where
15 K: Send + Sync,
16 V: Send + Sync,
17{
18 type Error: std::error::Error + Send + Sync + 'static;
20
21 async fn get(&self, key: &K) -> Result<Option<V>, Self::Error>;
23
24 async fn set(&self, key: &K, value: V, ttl: Duration) -> Result<(), Self::Error>;
26
27 async fn delete(&self, key: &K) -> Result<bool, Self::Error>;
29
30 async fn exists(&self, key: &K) -> Result<bool, Self::Error>;
32
33 async fn expire(&self, key: &K, ttl: Duration) -> Result<bool, Self::Error>;
35
36 async fn ttl(&self, key: &K) -> Result<Option<Duration>, Self::Error>;
38
39 async fn clear(&self) -> Result<(), Self::Error>;
41
42 async fn size(&self) -> Result<usize, Self::Error>;
44
45 async fn get_many(&self, keys: &[K]) -> Result<Vec<Option<V>>, Self::Error> {
47 let mut results = Vec::with_capacity(keys.len());
48 for key in keys {
49 results.push(self.get(key).await?);
50 }
51 Ok(results)
52 }
53
54 async fn set_many(&self, items: &[(K, V, Duration)]) -> Result<(), Self::Error>
56 where
57 K: Clone,
58 V: Clone,
59 {
60 for (key, value, ttl) in items {
61 self.set(key, value.clone(), *ttl).await?;
62 }
63 Ok(())
64 }
65}
66
67pub trait CacheKey: Send + Sync + Clone + std::fmt::Debug + std::hash::Hash + Eq {
71 fn to_cache_key(&self) -> String;
73
74 fn from_cache_key(s: &str) -> Result<Self, CacheError>
76 where
77 Self: Sized;
78}
79
80pub trait CacheValue: Send + Sync + Clone + std::fmt::Debug {
84 fn to_bytes(&self) -> Result<Vec<u8>, CacheError>;
86
87 fn from_bytes(bytes: &[u8]) -> Result<Self, CacheError>
89 where
90 Self: Sized;
91}
92
93impl CacheKey for String {
95 fn to_cache_key(&self) -> String {
96 self.clone()
97 }
98
99 fn from_cache_key(s: &str) -> Result<Self, CacheError> {
100 Ok(s.to_string())
101 }
102}
103
104impl<T> CacheValue for T
106where
107 T: Serialize + for<'de> Deserialize<'de> + Send + Sync + Clone + std::fmt::Debug,
108{
109 fn to_bytes(&self) -> Result<Vec<u8>, CacheError> {
110 bincode::serialize(self).map_err(CacheError::Serialization)
111 }
112
113 fn from_bytes(bytes: &[u8]) -> Result<Self, CacheError> {
114 bincode::deserialize(bytes).map_err(CacheError::Deserialization)
115 }
116}
117
118#[derive(Debug, Clone)]
120pub struct CacheStats {
121 pub hits: u64,
123 pub misses: u64,
125 pub key_count: usize,
127 pub memory_usage: usize,
129 pub hit_rate: f64,
131}
132
133impl CacheStats {
134 pub fn new() -> Self {
135 Self {
136 hits: 0,
137 misses: 0,
138 key_count: 0,
139 memory_usage: 0,
140 hit_rate: 0.0,
141 }
142 }
143
144 pub fn calculate_hit_rate(&mut self) {
145 let total = self.hits + self.misses;
146 if total > 0 {
147 self.hit_rate = self.hits as f64 / total as f64;
148 }
149 }
150}
151
152impl Default for CacheStats {
153 fn default() -> Self {
154 Self::new()
155 }
156}
157
158#[async_trait]
160pub trait CacheWithStats<K, V>: Cache<K, V>
161where
162 K: Send + Sync,
163 V: Send + Sync,
164{
165 async fn stats(&self) -> Result<CacheStats, Self::Error>;
167
168 async fn reset_stats(&self) -> Result<(), Self::Error>;
170}
171
172#[derive(Debug, Clone)]
174pub enum CacheEvent<K, V> {
175 Hit { key: K },
177 Miss { key: K },
179 Set { key: K, value: V },
181 Delete { key: K },
183 Expire { key: K },
185 Clear,
187}
188
189#[async_trait]
191pub trait CacheEventListener<K, V>: Send + Sync
192where
193 K: Send + Sync,
194 V: Send + Sync,
195{
196 async fn on_event(&self, event: CacheEvent<K, V>);
198}
199
200#[derive(Debug, thiserror::Error)]
202pub enum CacheError {
203 #[error("Connection failed: {0}")]
204 Connection(String),
205
206 #[error("Serialization failed: {0}")]
207 Serialization(#[from] Box<bincode::ErrorKind>),
208
209 #[error("Deserialization failed: {0}")]
210 Deserialization(Box<bincode::ErrorKind>),
211
212 #[error("Key not found: {key}")]
213 KeyNotFound { key: String },
214
215 #[error("Cache is full")]
216 CacheFull,
217
218 #[error("Invalid TTL: {ttl_ms}ms")]
219 InvalidTTL { ttl_ms: u64 },
220
221 #[error("Cache operation timeout")]
222 Timeout,
223
224 #[error("Cache backend error: {0}")]
225 Backend(String),
226
227 #[error("Other cache error: {0}")]
228 Other(String),
229}
230
231impl CacheError {
232 pub fn connection(msg: impl Into<String>) -> Self {
233 Self::Connection(msg.into())
234 }
235
236 pub fn key_not_found(key: impl Into<String>) -> Self {
237 Self::KeyNotFound { key: key.into() }
238 }
239
240 pub fn backend(msg: impl Into<String>) -> Self {
241 Self::Backend(msg.into())
242 }
243
244 pub fn other(msg: impl Into<String>) -> Self {
245 Self::Other(msg.into())
246 }
247}