sockudo_cache/
memory_cache_manager.rs1use async_trait::async_trait;
2use moka::future::Cache;
3use sockudo_core::cache::CacheManager;
4use sockudo_core::error::Result;
5use sockudo_core::options::MemoryCacheOptions;
6use std::time::Duration;
7
8#[derive(Clone)]
10pub struct MemoryCacheManager {
11 cache: Cache<String, String, ahash::RandomState>,
13 options: MemoryCacheOptions,
15 prefix: String,
17}
18
19impl MemoryCacheManager {
20 pub fn new(prefix: String, options: MemoryCacheOptions) -> Self {
22 let cache_builder = Cache::builder()
23 .max_capacity(options.max_capacity)
24 .name(format!("sockudo-memory-cache-{prefix}").as_str());
25
26 let cache = if options.ttl > 0 {
27 cache_builder.time_to_live(Duration::from_secs(options.ttl))
28 } else {
29 cache_builder
30 }
31 .build_with_hasher(ahash::RandomState::new());
32
33 Self {
34 cache,
35 options,
36 prefix,
37 }
38 }
39
40 fn prefixed_key(&self, key: &str) -> String {
42 format!("{}:{}", self.prefix, key)
43 }
44}
45
46#[async_trait]
47impl CacheManager for MemoryCacheManager {
48 async fn has(&self, key: &str) -> Result<bool> {
49 let prefixed_key = self.prefixed_key(key);
50 let exists = self.cache.get(&prefixed_key).await.is_some();
51 Ok(exists)
52 }
53
54 async fn get(&self, key: &str) -> Result<Option<String>> {
55 let prefixed_key = self.prefixed_key(key);
56 Ok(self.cache.get(&prefixed_key).await)
57 }
58
59 async fn set(&self, key: &str, value: &str, _ttl_seconds: u64) -> Result<()> {
60 let prefixed_key = self.prefixed_key(key);
61 let value_string = value.to_string();
62
63 self.cache.insert(prefixed_key, value_string).await;
64 Ok(())
65 }
66
67 async fn remove(&self, key: &str) -> Result<()> {
68 let prefixed_key = self.prefixed_key(key);
69 self.cache.invalidate(&prefixed_key).await;
70 Ok(())
71 }
72
73 async fn disconnect(&self) -> Result<()> {
74 self.cache.invalidate_all();
75 Ok(())
76 }
77
78 async fn ttl(&self, key: &str) -> Result<Option<Duration>> {
79 let prefixed_key = self.prefixed_key(key);
80 if self.cache.contains_key(&prefixed_key) {
81 if self.options.ttl > 0 {
82 Ok(Some(Duration::from_secs(self.options.ttl)))
83 } else {
84 Ok(None)
85 }
86 } else {
87 Ok(None)
88 }
89 }
90}
91
92impl MemoryCacheManager {
93 pub async fn delete(&mut self, key: &str) -> Result<bool> {
95 let prefixed_key = self.prefixed_key(key);
96 if self.cache.contains_key(&prefixed_key) {
97 self.cache.invalidate(&prefixed_key).await;
98 Ok(true)
99 } else {
100 Ok(false)
101 }
102 }
103
104 pub async fn get_many(&mut self, keys: &[&str]) -> Result<Vec<Option<String>>> {
106 let mut results = Vec::with_capacity(keys.len());
107 for &key in keys {
108 results.push(self.get(key).await?);
109 }
110 Ok(results)
111 }
112
113 pub async fn set_many(&mut self, pairs: &[(&str, &str)], _ttl_seconds: u64) -> Result<()> {
115 for (key, value) in pairs {
116 let prefixed_key = self.prefixed_key(key);
117 let value_string = value.to_string();
118 self.cache.insert(prefixed_key, value_string).await;
119 }
120 Ok(())
121 }
122
123 pub async fn get_all_entries(&self) -> Vec<(String, String, Option<Duration>)> {
130 let mut entries = Vec::new();
131 let prefix_len = self.prefix.len() + 1; for (key, value) in self.cache.iter() {
134 if key.starts_with(&format!("{}:", self.prefix)) {
135 let unprefixed_key = key[prefix_len..].to_string();
136 let ttl = if self.options.ttl > 0 {
137 Some(Duration::from_secs(self.options.ttl))
138 } else {
139 None
140 };
141 entries.push((unprefixed_key, value.clone(), ttl));
142 }
143 }
144
145 entries
146 }
147}