Skip to main content

mocra_core/cacheable/cache_service/
cache_able.rs

1use super::service::CacheService;
2use crate::errors::CacheError;
3use serde::{Deserialize, Serialize};
4use std::time::Duration;
5
6#[async_trait::async_trait]
7pub trait CacheAble: Send + Sync + Sized
8where
9    Self: Serialize + for<'de> Deserialize<'de> + 'static,
10{
11    fn field() -> impl AsRef<str>;
12
13    fn serialized_size_hint(&self) -> Option<usize> {
14        None
15    }
16
17    fn clone_for_serialize(&self) -> Option<Self> {
18        None
19    }
20
21    async fn send(&self, id: &str, sync: &CacheService) -> Result<(), CacheError> {
22        let key = Self::cache_id(id, sync);
23
24        let content = if self
25            .serialized_size_hint()
26            .map_or(false, |size| size >= sync.serialize_blocking_threshold)
27        {
28            if let Some(data) = self.clone_for_serialize() {
29                tokio::task::spawn_blocking(move || serde_json::to_vec(&data))
30                    .await
31                    .map_err(|e| CacheError::Pool(e.to_string()))??
32            } else {
33                serde_json::to_vec(self)?
34            }
35        } else {
36            serde_json::to_vec(self)?
37        };
38
39        sync.backend.set(&key, &content, sync.default_ttl).await?;
40        Ok(())
41    }
42
43    /// Store this value in the cache with no TTL (persistent until explicitly deleted).
44    async fn send_persistent(&self, id: &str, sync: &CacheService) -> Result<(), CacheError> {
45        let key = Self::cache_id(id, sync);
46        let content = if self
47            .serialized_size_hint()
48            .map_or(false, |size| size >= sync.serialize_blocking_threshold)
49        {
50            if let Some(data) = self.clone_for_serialize() {
51                tokio::task::spawn_blocking(move || serde_json::to_vec(&data))
52                    .await
53                    .map_err(|e| CacheError::Pool(e.to_string()))??
54            } else {
55                serde_json::to_vec(self)?
56            }
57        } else {
58            serde_json::to_vec(self)?
59        };
60        sync.backend.set(&key, &content, None).await?;
61        Ok(())
62    }
63
64    async fn send_with_ttl(
65        &self,
66        id: &str,
67        sync: &CacheService,
68        ttl: Duration,
69    ) -> Result<(), CacheError> {
70        let key = Self::cache_id(id, sync);
71        let content = if self
72            .serialized_size_hint()
73            .map_or(false, |size| size >= sync.serialize_blocking_threshold)
74        {
75            if let Some(data) = self.clone_for_serialize() {
76                tokio::task::spawn_blocking(move || serde_json::to_vec(&data))
77                    .await
78                    .map_err(|e| CacheError::Pool(e.to_string()))??
79            } else {
80                serde_json::to_vec(self)?
81            }
82        } else {
83            serde_json::to_vec(self)?
84        };
85        sync.backend.set(&key, &content, Some(ttl)).await?;
86        Ok(())
87    }
88
89    async fn send_nx(
90        &self,
91        id: &str,
92        sync: &CacheService,
93        ttl: Option<Duration>,
94    ) -> Result<bool, CacheError> {
95        let key = Self::cache_id(id, sync);
96        let content = if self
97            .serialized_size_hint()
98            .map_or(false, |size| size >= sync.serialize_blocking_threshold)
99        {
100            if let Some(data) = self.clone_for_serialize() {
101                tokio::task::spawn_blocking(move || serde_json::to_vec(&data))
102                    .await
103                    .map_err(|e| CacheError::Pool(e.to_string()))??
104            } else {
105                serde_json::to_vec(self)?
106            }
107        } else {
108            serde_json::to_vec(self)?
109        };
110        sync.backend.set_nx(&key, &content, ttl).await
111    }
112
113    async fn sync(id: &str, sync: &CacheService) -> Result<Option<Self>, CacheError> {
114        let key = Self::cache_id(id, sync);
115        if let Some(bytes) = sync.backend.get(&key).await? {
116            let val = serde_json::from_slice(&bytes).map_err(CacheError::Serde)?;
117            Ok(Some(val))
118        } else {
119            Ok(None)
120        }
121    }
122
123    async fn delete(id: &str, sync: &CacheService) -> Result<(), CacheError> {
124        let key = Self::cache_id(id, sync);
125        sync.backend.del(&key).await?;
126        Ok(())
127    }
128
129    async fn scan(pattern_suffix: &str, sync: &CacheService) -> Result<Vec<String>, CacheError> {
130        let pattern = format!(
131            "{}:{}:{}",
132            sync.namespace,
133            Self::field().as_ref(),
134            pattern_suffix
135        );
136        sync.backend.keys(&pattern).await
137    }
138
139    fn cache_id(id: &str, cache: &CacheService) -> String {
140        format!("{}:{}:{id}", cache.namespace, Self::field().as_ref())
141    }
142}