Skip to main content

sockudo_cache/
factory.rs

1#![allow(dead_code)]
2
3#[cfg(any(feature = "redis", feature = "redis-cluster"))]
4use crate::fallback_cache_manager::FallbackCacheManager;
5use crate::memory_cache_manager::MemoryCacheManager;
6#[cfg(feature = "redis")]
7use crate::redis_cache_manager::{
8    RedisCacheConfig as StandaloneRedisCacheConfig, RedisCacheManager,
9};
10#[cfg(feature = "redis-cluster")]
11use crate::redis_cluster_cache_manager::{RedisClusterCacheConfig, RedisClusterCacheManager};
12use sockudo_core::cache::CacheManager;
13use sockudo_core::error::{Error, Result};
14use sockudo_core::options::{CacheConfig, CacheDriver, MemoryCacheOptions, RedisConnection};
15use std::sync::Arc;
16use tracing::info;
17
18pub struct CacheManagerFactory;
19
20impl CacheManagerFactory {
21    #[allow(unused_variables)]
22    pub async fn create(
23        config: &CacheConfig,
24        global_redis_conn_details: &RedisConnection,
25    ) -> Result<Arc<dyn CacheManager + Send + Sync>> {
26        info!(
27            "{}",
28            format!("Initializing CacheManager with driver: {:?}", config.driver)
29        );
30
31        match config.driver {
32            #[cfg(feature = "redis")]
33            CacheDriver::Redis => {
34                #[cfg(feature = "redis-cluster")]
35                if config.redis.cluster_mode {
36                    info!("{}", "Cache: Using Redis Cluster driver.".to_string());
37                    if global_redis_conn_details.cluster_nodes.is_empty() {
38                        tracing::error!("{}", "Cache: Redis cluster mode enabled, but no cluster_nodes configured in database.redis section.".to_string());
39                        return Err(Error::Cache(
40                            "Cache: Redis cluster nodes not configured.".to_string(),
41                        ));
42                    }
43                    let nodes: Vec<String> = global_redis_conn_details
44                        .cluster_nodes
45                        .iter()
46                        .map(|node| node.to_url())
47                        .collect();
48
49                    let prefix =
50                        config.redis.prefix.clone().unwrap_or_else(|| {
51                            global_redis_conn_details.key_prefix.clone() + "cache:"
52                        });
53
54                    let cluster_cache_config = RedisClusterCacheConfig {
55                        nodes,
56                        prefix,
57                        ..Default::default()
58                    };
59                    let manager = RedisClusterCacheManager::new(cluster_cache_config).await?;
60                    return Ok(Arc::new(manager));
61                }
62
63                #[cfg(not(feature = "redis-cluster"))]
64                if config.redis.cluster_mode {
65                    info!("{}", "Cache: Redis cluster mode requested but redis-cluster feature not enabled. Falling back to standalone Redis.".to_string());
66                }
67
68                info!("{}", "Cache: Using standalone Redis driver.".to_string());
69                let redis_url = config
70                    .redis
71                    .url_override
72                    .clone()
73                    .unwrap_or_else(|| global_redis_conn_details.to_url());
74
75                let prefix = config
76                    .redis
77                    .prefix
78                    .clone()
79                    .unwrap_or_else(|| global_redis_conn_details.key_prefix.clone() + "cache:");
80
81                let standalone_redis_cache_config = StandaloneRedisCacheConfig {
82                    url: redis_url,
83                    prefix,
84                    ..Default::default()
85                };
86                let manager = RedisCacheManager::new(standalone_redis_cache_config).await?;
87                let fallback_manager = FallbackCacheManager::new_with_health_check(
88                    Box::new(manager),
89                    config.memory.clone(),
90                )
91                .await;
92                Ok(Arc::new(fallback_manager))
93            }
94            #[cfg(feature = "redis-cluster")]
95            CacheDriver::RedisCluster => {
96                info!(
97                    "{}",
98                    "Cache: Using Redis Cluster driver (explicitly selected).".to_string()
99                );
100                if global_redis_conn_details.cluster_nodes.is_empty() {
101                    tracing::error!("{}", "Cache: Redis cluster driver selected, but no cluster_nodes configured in database.redis section.".to_string());
102                    return Err(Error::Cache(
103                        "Cache: Redis cluster nodes not configured for explicit cluster driver."
104                            .to_string(),
105                    ));
106                }
107                let nodes: Vec<String> = global_redis_conn_details
108                    .cluster_nodes
109                    .iter()
110                    .map(|node| node.to_url())
111                    .collect();
112
113                let prefix = config
114                    .redis
115                    .prefix
116                    .clone()
117                    .unwrap_or_else(|| global_redis_conn_details.key_prefix.clone() + "cache:");
118
119                let cluster_cache_config = RedisClusterCacheConfig {
120                    nodes,
121                    prefix,
122                    ..Default::default()
123                };
124                let manager = RedisClusterCacheManager::new(cluster_cache_config).await?;
125                let fallback_manager = FallbackCacheManager::new_with_health_check(
126                    Box::new(manager),
127                    config.memory.clone(),
128                )
129                .await;
130                Ok(Arc::new(fallback_manager))
131            }
132            CacheDriver::Memory => {
133                info!("{}", "Using memory cache manager.".to_string());
134                let _mem_config = MemoryCacheOptions {
135                    ttl: config.memory.ttl,
136                    cleanup_interval: config.memory.cleanup_interval,
137                    max_capacity: config.memory.max_capacity,
138                };
139                let manager =
140                    MemoryCacheManager::new("default_mem_cache".to_string(), config.memory.clone());
141                Ok(Arc::new(manager))
142            }
143            CacheDriver::None => {
144                info!(
145                    "{}",
146                    "Cache driver is 'None'. Cache will be disabled.".to_string()
147                );
148                Err(Error::Cache(
149                    "Cache driver explicitly set to 'None'.".to_string(),
150                ))
151            }
152            #[cfg(not(feature = "redis"))]
153            CacheDriver::Redis => {
154                info!(
155                    "{}",
156                    "Redis cache manager requested but not compiled in. Falling back to memory cache."
157                );
158                let manager =
159                    MemoryCacheManager::new("default_mem_cache".to_string(), config.memory.clone());
160                Ok(Arc::new(manager))
161            }
162            #[cfg(not(feature = "redis-cluster"))]
163            CacheDriver::RedisCluster => {
164                info!(
165                    "Redis Cluster cache manager requested but not compiled in. Falling back to memory cache."
166                );
167                let manager =
168                    MemoryCacheManager::new("default_mem_cache".to_string(), config.memory.clone());
169                Ok(Arc::new(manager))
170            }
171        }
172    }
173}