oxcache/client/
mod.rs

1//! Copyright (c) 2025-2026, Kirky.X
2//!
3//! MIT License
4//!
5//! 该模块定义了缓存客户端的接口和实现。
6
7pub mod db_loader;
8
9#[cfg(feature = "l1-moka")]
10pub mod l1;
11
12#[cfg(feature = "l2-redis")]
13pub mod l2;
14
15#[cfg(all(feature = "l1-moka", feature = "l2-redis"))]
16pub mod two_level;
17
18#[cfg(feature = "redis-native")]
19pub mod redis_native;
20
21#[cfg(feature = "ttl-control")]
22pub mod ttl_control;
23
24#[cfg(feature = "tiered-cache")]
25pub mod tiered_cache;
26
27use crate::error::Result;
28use async_trait::async_trait;
29use std::any::Any;
30
31use crate::serialization::Serializer;
32use serde::{de::DeserializeOwned, Serialize};
33use tracing::instrument;
34
35/// 缓存扩展特征
36///
37/// 提供类型安全的缓存操作接口
38#[async_trait]
39pub trait CacheExt: CacheOps {
40    /// 获取缓存值(反序列化)
41    #[instrument(skip(self), level = "debug")]
42    async fn get<T: DeserializeOwned + Send>(&self, key: &str) -> Result<Option<T>> {
43        let bytes = self.get_bytes(key).await?;
44        match bytes {
45            Some(data) => {
46                let val = self.serializer().deserialize(&data)?;
47                Ok(Some(val))
48            }
49            None => Ok(None),
50        }
51    }
52
53    /// 设置缓存值(序列化)
54    #[instrument(skip(self, value), level = "debug")]
55    async fn set<T: Serialize + Send + Sync>(
56        &self,
57        key: &str,
58        value: &T,
59        ttl: Option<u64>,
60    ) -> Result<()> {
61        let bytes = self.serializer().serialize(value)?;
62        self.set_bytes(key, bytes, ttl).await
63    }
64
65    /// 仅设置 L1 缓存(如果支持)
66    #[instrument(skip(self, value), level = "debug")]
67    async fn set_l1_only<T: Serialize + Send + Sync>(
68        &self,
69        key: &str,
70        value: &T,
71        ttl: Option<u64>,
72    ) -> Result<()> {
73        let bytes = self.serializer().serialize(value)?;
74        self.set_l1_bytes(key, bytes, ttl).await
75    }
76
77    #[instrument(skip(self, value), level = "debug")]
78    async fn set_l2_only<T: Serialize + Send + Sync>(
79        &self,
80        key: &str,
81        value: &T,
82        ttl: Option<u64>,
83    ) -> Result<()> {
84        let bytes = self.serializer().serialize(value)?;
85        self.set_l2_bytes(key, bytes, ttl).await
86    }
87
88    /// 获取缓存值,如果不存在则调用回调函数获取并缓存
89    ///
90    /// # 参数
91    ///
92    /// * `key` - 缓存键
93    /// * `ttl` - 缓存时间(秒)
94    /// * `fetch` - 当缓存未命中时调用的回调函数
95    ///
96    /// # 返回值
97    ///
98    /// 返回缓存的值或从回调函数获取的值
99    ///
100    /// # 示例
101    ///
102    /// ```rust,ignore
103    /// let user = cache
104    ///     .get_or_fetch("user:123", Some(3600), || async {
105    ///         database::get_user("123").await
106    ///     })
107    ///     .await?;
108    /// ```
109    #[instrument(skip(self, fetch), level = "debug")]
110    async fn get_or_fetch<T, F, Fut>(&self, key: &str, ttl: Option<u64>, fetch: F) -> Result<T>
111    where
112        T: DeserializeOwned + Serialize + Send + Sync + Clone,
113        F: FnOnce() -> Fut + Send,
114        Fut: std::future::Future<Output = Result<T>> + Send,
115    {
116        // 尝试从缓存获取
117        if let Some(cached) = self.get::<T>(key).await? {
118            return Ok(cached);
119        }
120
121        // 缓存未命中,从数据源获取
122        let value = fetch().await?;
123
124        // 缓存结果
125        self.set(key, &value, ttl).await?;
126
127        Ok(value)
128    }
129
130    /// 尝试获取,如果不存在返回 None(不触发 fetch)
131    ///
132    /// 这是一个便捷方法,避免使用 Option 处理
133    #[instrument(skip(self), level = "debug")]
134    async fn try_get<T: DeserializeOwned + Send>(&self, key: &str) -> Result<Option<T>> {
135        self.get(key).await
136    }
137
138    /// 删除并返回旧值
139    ///
140    /// # 参数
141    ///
142    /// * `key` - 缓存键
143    ///
144    /// # 返回值
145    ///
146    /// 返回被删除的值(如果存在)
147    #[instrument(skip(self), level = "debug")]
148    async fn remove<T: DeserializeOwned + Send>(&self, key: &str) -> Result<Option<T>> {
149        let old_value = self.get::<T>(key).await?;
150        self.delete(key).await?;
151        Ok(old_value)
152    }
153
154    /// 检查键是否存在
155    ///
156    /// # 参数
157    ///
158    /// * `key` - 缓存键
159    ///
160    /// # 返回值
161    ///
162    /// 如果键存在返回 true,否则返回 false
163    #[instrument(skip(self), level = "debug")]
164    async fn contains(&self, key: &str) -> Result<bool> {
165        Ok(self.get_bytes(key).await?.is_some())
166    }
167}
168
169impl<T: CacheOps + ?Sized> CacheExt for T {}
170
171/// 缓存操作特征
172///
173/// 定义缓存系统的基本操作接口
174#[async_trait]
175pub trait CacheOps: Send + Sync + Any {
176    /// 获取缓存值
177    ///
178    /// # 参数
179    ///
180    /// * `key` - 缓存键
181    ///
182    /// # 返回值
183    ///
184    /// 返回缓存值,如果不存在则返回None
185    async fn get_bytes(&self, key: &str) -> Result<Option<Vec<u8>>>;
186
187    /// 获取 L1 缓存值(字节)
188    async fn get_l1_bytes(&self, _key: &str) -> Result<Option<Vec<u8>>> {
189        Err(crate::error::CacheError::NotSupported(
190            "get_l1_bytes".to_string(),
191        ))
192    }
193
194    /// 获取 L2 缓存值(字节)
195    async fn get_l2_bytes(&self, _key: &str) -> Result<Option<Vec<u8>>> {
196        Err(crate::error::CacheError::NotSupported(
197            "get_l2_bytes".to_string(),
198        ))
199    }
200
201    /// 设置缓存值
202    ///
203    /// # 参数
204    ///
205    /// * `key` - 缓存键
206    /// * `value` - 缓存值
207    /// * `ttl` - 过期时间(秒),None表示使用默认值
208    ///
209    /// # 返回值
210    ///
211    /// 返回操作结果
212    async fn set_bytes(&self, key: &str, value: Vec<u8>, ttl: Option<u64>) -> Result<()>;
213
214    /// 设置 L1 缓存值(字节)
215    async fn set_l1_bytes(&self, _key: &str, _value: Vec<u8>, _ttl: Option<u64>) -> Result<()> {
216        Err(crate::error::CacheError::NotSupported(
217            "set_l1_bytes".to_string(),
218        ))
219    }
220
221    /// 设置 L2 缓存值(字节)
222    async fn set_l2_bytes(&self, _key: &str, _value: Vec<u8>, _ttl: Option<u64>) -> Result<()> {
223        Err(crate::error::CacheError::NotSupported(
224            "set_l2_bytes".to_string(),
225        ))
226    }
227
228    /// 尝试获取分布式锁
229    ///
230    /// 使用 SET NX PX 实现,自动生成安全的随机锁值
231    ///
232    /// # 参数
233    ///
234    /// * `key` - 锁的键
235    /// * `ttl` - 锁的过期时间(秒)
236    ///
237    /// # 返回值
238    ///
239    /// * `Ok(Some(value))` - 成功获取锁,value 为生成的锁值
240    /// * `Ok(None)` - 锁已被其他进程持有
241    /// * `Err(...)` - 发生错误
242    async fn lock(&self, _key: &str, _ttl: u64) -> Result<Option<String>> {
243        Ok(None)
244    }
245
246    /// 释放分布式锁
247    ///
248    /// # 参数
249    ///
250    /// * `key` - 锁的键
251    /// * `value` - 锁的值(必须匹配才能释放)
252    ///
253    /// # 返回值
254    ///
255    /// 成功释放返回 true,否则返回 false(例如锁不存在或值不匹配)
256    async fn unlock(&self, _key: &str, _value: &str) -> Result<bool> {
257        Ok(false)
258    }
259
260    /// 删除缓存项
261    ///
262    /// # 参数
263    ///
264    /// * `key` - 缓存键
265    ///
266    /// # 返回值
267    ///
268    /// 返回操作结果
269    async fn delete(&self, key: &str) -> Result<()>;
270
271    /// 获取序列化器
272    ///
273    /// 返回当前客户端使用的序列化器
274    fn serializer(&self) -> &crate::serialization::SerializerEnum;
275
276    /// 将 trait object 转换为 Any,用于向下转型
277    fn as_any(&self) -> &dyn Any;
278
279    /// 将 `Arc<Trait>` 转换为 `Arc<dyn Any>`,支持 Arc 下的向下转型
280    fn into_any_arc(self: std::sync::Arc<Self>) -> std::sync::Arc<dyn Any + Send + Sync>;
281
282    /// 清空 L1 缓存
283    ///
284    /// # 返回值
285    ///
286    /// 返回操作结果
287    async fn clear_l1(&self) -> Result<()> {
288        Err(crate::error::CacheError::NotSupported(
289            "clear_l1".to_string(),
290        ))
291    }
292
293    /// 清空 L2 缓存
294    ///
295    /// # 返回值
296    ///
297    /// 返回操作结果
298    async fn clear_l2(&self) -> Result<()> {
299        Err(crate::error::CacheError::NotSupported(
300            "clear_l2".to_string(),
301        ))
302    }
303
304    /// 清空 WAL 日志
305    ///
306    /// # 返回值
307    ///
308    /// 返回操作结果
309    async fn clear_wal(&self) -> Result<()> {
310        Err(crate::error::CacheError::NotSupported(
311            "clear_wal".to_string(),
312        ))
313    }
314
315    /// 优雅关闭客户端
316    ///
317    /// 关闭所有后台任务,释放资源
318    async fn shutdown(&self) -> Result<()> {
319        Ok(())
320    }
321}