diff --git a/src/basic/keywords/add_suggestion.rs b/src/basic/keywords/add_suggestion.rs index 58a710f0..76607db6 100644 --- a/src/basic/keywords/add_suggestion.rs +++ b/src/basic/keywords/add_suggestion.rs @@ -1,13 +1,84 @@ use crate::core::shared::models::UserSession; use crate::core::shared::state::AppState; use log::{error, info, trace}; +use once_cell::sync::Lazy; use rhai::{Dynamic, Engine}; use serde_json::json; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::time::Duration; +static REDIS_CONN: Lazy>> = Lazy::new(|| Mutex::new(None)); + fn get_redis_connection(cache_client: &Arc) -> Option { - let timeout = Duration::from_secs(2); + // Try to reuse existing connection + if let Ok(mut guard) = REDIS_CONN.lock() { + if let Some(ref mut conn) = *guard { + match redis::cmd("PING").query::(conn) { + Ok(_) => return Some(conn.clone()), + Err(_) => *guard = None, + } + } + } + + // Create new connection + let timeout = Duration::from_millis(50); + if let Ok(conn) = cache_client.get_connection_with_timeout(timeout) { + if let Ok(mut guard) = REDIS_CONN.lock() { + *guard = Some(conn.clone()); + } + Some(conn) + } else { + None + } +} + +impl RedisPool { + fn new(client: &Arc) -> Option { + let timeout = Duration::from_millis(100); + client + .get_connection_with_timeout(timeout) + .ok() + .map(|conn| Self { + conn: Mutex::new(Some(conn)), + }) + } + + fn with_connection(&self, op: F) -> Option + where + F: FnOnce(&mut redis::Connection) -> redis::RedisResult, + { + let mut guard = self.conn.lock().ok()?; + let conn = guard.as_mut()?; + + match op(conn) { + Ok(result) => { + // Connection still valid, put it back + Some(result) + } + Err(_) => { + // Connection failed, try to get a new one + // For simplicity, just return None and caller will retry + *guard = None; + None + } + } + } +} + +fn get_redis_pool(cache_client: &Arc) -> Option> { + static mut POOL: Option> = None; + static mut ONCE: std::sync::Once = std::sync::Once::INIT; + + unsafe { + ONCE.call_once(|| { + POOL = RedisPool::new(cache_client).map(Arc::new); + }); + POOL.clone() + } +} + +fn get_redis_connection(cache_client: &Arc) -> Option { + let timeout = Duration::from_millis(50); cache_client.get_connection_with_timeout(timeout).ok() }