sockudo 3.0.0

A simple, fast, and secure WebSocket server for real-time applications.
Documentation
#![allow(dead_code)]

// src/cache/factory.rs
#[cfg(any(feature = "redis", feature = "redis-cluster"))]
use crate::cache::fallback_cache_manager::FallbackCacheManager;
use crate::cache::manager::CacheManager;
use crate::cache::memory_cache_manager::MemoryCacheManager; // Assuming MemoryCacheConfig is from options
#[cfg(feature = "redis")]
use crate::cache::redis_cache_manager::{
    RedisCacheConfig as StandaloneRedisCacheConfig, RedisCacheManager,
};
#[cfg(feature = "redis-cluster")]
use crate::cache::redis_cluster_cache_manager::{
    RedisClusterCacheConfig, RedisClusterCacheManager,
};
use crate::error::{Error, Result};

use crate::options::{CacheConfig, CacheDriver, MemoryCacheOptions, RedisConnection};
use std::sync::Arc;
use tokio::sync::Mutex;
use tracing::info;

pub struct CacheManagerFactory;

impl CacheManagerFactory {
    #[allow(unused_variables)]
    pub async fn create(
        config: &CacheConfig,
        global_redis_conn_details: &RedisConnection,
    ) -> Result<Arc<Mutex<dyn CacheManager + Send + Sync>>> {
        // Corrected return type
        info!(
            "{}",
            format!("Initializing CacheManager with driver: {:?}", config.driver)
        );

        match config.driver {
            #[cfg(feature = "redis")]
            CacheDriver::Redis => {
                #[cfg(feature = "redis-cluster")]
                if config.redis.cluster_mode {
                    info!("{}", "Cache: Using Redis Cluster driver.".to_string());
                    if global_redis_conn_details.cluster_nodes.is_empty() {
                        tracing::error!("{}", "Cache: Redis cluster mode enabled, but no cluster_nodes configured in database.redis section.".to_string());
                        return Err(Error::Cache(
                            "Cache: Redis cluster nodes not configured.".to_string(),
                        ));
                    }
                    let nodes: Vec<String> = global_redis_conn_details
                        .cluster_nodes
                        .iter()
                        .map(|node| node.to_url())
                        .collect();

                    let prefix =
                        config.redis.prefix.clone().unwrap_or_else(|| {
                            global_redis_conn_details.key_prefix.clone() + "cache:"
                        });

                    let cluster_cache_config = RedisClusterCacheConfig {
                        nodes,
                        prefix,
                        ..Default::default()
                    };
                    let manager = RedisClusterCacheManager::new(cluster_cache_config).await?;
                    return Ok(Arc::new(Mutex::new(manager)));
                }

                #[cfg(not(feature = "redis-cluster"))]
                if config.redis.cluster_mode {
                    info!("{}", "Cache: Redis cluster mode requested but redis-cluster feature not enabled. Falling back to standalone Redis.".to_string());
                }

                info!("{}", "Cache: Using standalone Redis driver.".to_string());
                let redis_url = config.redis.url_override.clone().unwrap_or_else(|| {
                    format!(
                        "redis://{}:{}",
                        global_redis_conn_details.host, global_redis_conn_details.port
                    )
                });

                let prefix = config
                    .redis
                    .prefix
                    .clone()
                    .unwrap_or_else(|| global_redis_conn_details.key_prefix.clone() + "cache:");

                let standalone_redis_cache_config = StandaloneRedisCacheConfig {
                    url: redis_url,
                    prefix,
                    ..Default::default()
                };
                let manager = RedisCacheManager::new(standalone_redis_cache_config).await?;
                let fallback_manager = FallbackCacheManager::new_with_health_check(
                    Box::new(manager),
                    config.memory.clone(),
                )
                .await;
                Ok(Arc::new(Mutex::new(fallback_manager)))
            }
            #[cfg(feature = "redis-cluster")]
            CacheDriver::RedisCluster => {
                info!(
                    "{}",
                    "Cache: Using Redis Cluster driver (explicitly selected).".to_string()
                );
                if global_redis_conn_details.cluster_nodes.is_empty() {
                    tracing::error!("{}", "Cache: Redis cluster driver selected, but no cluster_nodes configured in database.redis section.".to_string());
                    return Err(Error::Cache(
                        "Cache: Redis cluster nodes not configured for explicit cluster driver."
                            .to_string(),
                    ));
                }
                let nodes: Vec<String> = global_redis_conn_details
                    .cluster_nodes
                    .iter()
                    .map(|node| node.to_url())
                    .collect();

                let prefix = config
                    .redis
                    .prefix
                    .clone()
                    .unwrap_or_else(|| global_redis_conn_details.key_prefix.clone() + "cache:");

                let cluster_cache_config = RedisClusterCacheConfig {
                    nodes,
                    prefix,
                    ..Default::default()
                };
                let manager = RedisClusterCacheManager::new(cluster_cache_config).await?;
                let fallback_manager = FallbackCacheManager::new_with_health_check(
                    Box::new(manager),
                    config.memory.clone(),
                )
                .await;
                Ok(Arc::new(Mutex::new(fallback_manager)))
            }
            CacheDriver::Memory => {
                info!("{}", "Using memory cache manager.".to_string());
                // Assuming MemoryCacheOptions is the correct config struct for MemoryCacheManager
                let _mem_config = MemoryCacheOptions {
                    ttl: config.memory.ttl,
                    cleanup_interval: config.memory.cleanup_interval,
                    max_capacity: config.memory.max_capacity,
                };
                let manager =
                    MemoryCacheManager::new("default_mem_cache".to_string(), config.memory.clone()); // Pass prefix and MemoryCacheOptions
                Ok(Arc::new(Mutex::new(manager)))
            }
            CacheDriver::None => {
                info!(
                    "{}",
                    "Cache driver is 'None'. Cache will be disabled.".to_string()
                );
                Err(Error::Cache(
                    "Cache driver explicitly set to 'None'.".to_string(),
                ))
            }
            #[cfg(not(feature = "redis"))]
            CacheDriver::Redis => {
                info!(
                    "{}",
                    "Redis cache manager requested but not compiled in. Falling back to memory cache."
                );
                let manager =
                    MemoryCacheManager::new("default_mem_cache".to_string(), config.memory.clone());
                Ok(Arc::new(Mutex::new(manager)))
            }
            #[cfg(not(feature = "redis-cluster"))]
            CacheDriver::RedisCluster => {
                info!(
                    "Redis Cluster cache manager requested but not compiled in. Falling back to memory cache."
                );
                let manager =
                    MemoryCacheManager::new("default_mem_cache".to_string(), config.memory.clone());
                Ok(Arc::new(Mutex::new(manager)))
            }
        }
    }
}