//! NAC Lens连接管理系统 //! //! 实现连接池、心跳机制、超时处理和连接复用 use std::collections::HashMap; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; use serde::{Serialize, Deserialize}; use crate::error::{NacLensError, Result}; /// 连接状态 #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum ConnectionState { /// 未连接 Disconnected, /// 正在连接 Connecting, /// 已连接 Connected, /// 空闲 Idle, /// 繁忙 Busy, /// 正在关闭 Closing, /// 已关闭 Closed, /// 错误 Error, } /// 连接信息 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ConnectionInfo { /// 连接ID pub id: String, /// 远程地址 pub remote_addr: String, /// 连接状态 pub state: ConnectionState, /// 创建时间 pub created_at: u64, /// 最后活跃时间 pub last_active: u64, /// 最后心跳时间 pub last_heartbeat: u64, /// 请求计数 pub request_count: u64, /// 错误计数 pub error_count: u64, /// 是否可复用 pub reusable: bool, } /// 连接配置 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ConnectionConfig { /// 最大连接数 pub max_connections: usize, /// 最小连接数 pub min_connections: usize, /// 连接超时(秒) pub connect_timeout: u64, /// 空闲超时(秒) pub idle_timeout: u64, /// 心跳间隔(秒) pub heartbeat_interval: u64, /// 心跳超时(秒) pub heartbeat_timeout: u64, /// 最大重试次数 pub max_retries: u32, /// 重试延迟(秒) pub retry_delay: u64, /// 是否启用连接复用 pub enable_reuse: bool, } impl Default for ConnectionConfig { fn default() -> Self { Self { max_connections: 100, min_connections: 10, connect_timeout: 30, idle_timeout: 300, heartbeat_interval: 30, heartbeat_timeout: 10, max_retries: 3, retry_delay: 5, enable_reuse: true, } } } /// 连接池统计 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PoolStats { /// 总连接数 pub total_connections: usize, /// 活跃连接数 pub active_connections: usize, /// 空闲连接数 pub idle_connections: usize, /// 等待连接数 pub waiting_connections: usize, /// 总请求数 pub total_requests: u64, /// 总错误数 pub total_errors: u64, /// 平均响应时间(毫秒) pub avg_response_time: u64, } /// 连接 #[derive(Debug)] struct Connection { /// 连接信息 info: ConnectionInfo, /// 最后使用时间 last_used: Instant, /// 是否正在使用 in_use: bool, } /// 连接池 #[derive(Debug)] pub struct ConnectionPool { /// 配置 config: ConnectionConfig, /// 连接映射 connections: Arc>>, /// 下一个连接ID next_id: Arc>, /// 统计信息 stats: Arc>, } impl ConnectionPool { /// 创建新的连接池 pub fn new(config: ConnectionConfig) -> Self { Self { config, connections: Arc::new(Mutex::new(HashMap::new())), next_id: Arc::new(Mutex::new(1)), stats: Arc::new(Mutex::new(PoolStats { total_connections: 0, active_connections: 0, idle_connections: 0, waiting_connections: 0, total_requests: 0, total_errors: 0, avg_response_time: 0, })), } } /// 获取连接 pub fn get_connection(&self, remote_addr: &str) -> Result { let mut connections = self.connections.lock().unwrap(); // 查找可复用的空闲连接 if self.config.enable_reuse { for (id, conn) in connections.iter_mut() { if conn.info.remote_addr == remote_addr && conn.info.state == ConnectionState::Idle && !conn.in_use && conn.info.reusable { // 检查连接是否过期 if conn.last_used.elapsed().as_secs() < self.config.idle_timeout { conn.in_use = true; conn.info.state = ConnectionState::Busy; conn.info.last_active = Self::current_timestamp(); conn.last_used = Instant::now(); return Ok(id.clone()); } } } } // 检查是否达到最大连接数 if connections.len() >= self.config.max_connections { return Err(NacLensError::NetworkError( "Connection pool is full".to_string(), )); } // 创建新连接 let conn_id = self.create_connection(remote_addr)?; // 标记为使用中 if let Some(conn) = connections.get_mut(&conn_id) { conn.in_use = true; conn.info.state = ConnectionState::Busy; } Ok(conn_id) } /// 创建连接 fn create_connection(&self, remote_addr: &str) -> Result { let mut next_id = self.next_id.lock().unwrap(); let conn_id = format!("CONN-{:08}", *next_id); *next_id += 1; drop(next_id); let current_time = Self::current_timestamp(); let info = ConnectionInfo { id: conn_id.clone(), remote_addr: remote_addr.to_string(), state: ConnectionState::Connected, created_at: current_time, last_active: current_time, last_heartbeat: current_time, request_count: 0, error_count: 0, reusable: self.config.enable_reuse, }; let connection = Connection { info, last_used: Instant::now(), in_use: false, }; let mut connections = self.connections.lock().unwrap(); connections.insert(conn_id.clone(), connection); // 更新统计 let mut stats = self.stats.lock().unwrap(); stats.total_connections += 1; stats.active_connections += 1; Ok(conn_id) } /// 释放连接 pub fn release_connection(&self, conn_id: &str) -> Result<()> { let mut connections = self.connections.lock().unwrap(); if let Some(conn) = connections.get_mut(conn_id) { conn.in_use = false; conn.info.state = ConnectionState::Idle; conn.info.last_active = Self::current_timestamp(); conn.last_used = Instant::now(); // 更新统计 let mut stats = self.stats.lock().unwrap(); stats.active_connections = stats.active_connections.saturating_sub(1); stats.idle_connections += 1; Ok(()) } else { Err(NacLensError::NetworkError(format!( "Connection {} not found", conn_id ))) } } /// 关闭连接 pub fn close_connection(&self, conn_id: &str) -> Result<()> { let mut connections = self.connections.lock().unwrap(); if let Some(mut conn) = connections.remove(conn_id) { conn.info.state = ConnectionState::Closed; // 更新统计 let mut stats = self.stats.lock().unwrap(); stats.total_connections = stats.total_connections.saturating_sub(1); if conn.in_use { stats.active_connections = stats.active_connections.saturating_sub(1); } else { stats.idle_connections = stats.idle_connections.saturating_sub(1); } Ok(()) } else { Err(NacLensError::NetworkError(format!( "Connection {} not found", conn_id ))) } } /// 发送心跳 pub fn send_heartbeat(&self, conn_id: &str) -> Result<()> { let mut connections = self.connections.lock().unwrap(); if let Some(conn) = connections.get_mut(conn_id) { conn.info.last_heartbeat = Self::current_timestamp(); conn.info.last_active = Self::current_timestamp(); Ok(()) } else { Err(NacLensError::NetworkError(format!( "Connection {} not found", conn_id ))) } } /// 检查心跳超时 pub fn check_heartbeat_timeout(&self) -> Vec { let mut connections = self.connections.lock().unwrap(); let current_time = Self::current_timestamp(); let timeout = self.config.heartbeat_timeout; let mut timeout_connections = Vec::new(); for (id, conn) in connections.iter_mut() { let elapsed = current_time - conn.info.last_heartbeat; if elapsed > timeout && conn.info.state == ConnectionState::Connected { conn.info.state = ConnectionState::Error; timeout_connections.push(id.clone()); } } timeout_connections } /// 清理空闲连接 pub fn cleanup_idle_connections(&self) -> usize { let mut connections = self.connections.lock().unwrap(); let idle_timeout = self.config.idle_timeout; let mut to_remove = Vec::new(); for (id, conn) in connections.iter() { if !conn.in_use && conn.info.state == ConnectionState::Idle && conn.last_used.elapsed().as_secs() > idle_timeout { to_remove.push(id.clone()); } } let count = to_remove.len(); for id in to_remove { connections.remove(&id); } // 更新统计 let mut stats = self.stats.lock().unwrap(); stats.total_connections = stats.total_connections.saturating_sub(count); stats.idle_connections = stats.idle_connections.saturating_sub(count); count } /// 记录请求 pub fn record_request(&self, conn_id: &str, success: bool) -> Result<()> { let mut connections = self.connections.lock().unwrap(); if let Some(conn) = connections.get_mut(conn_id) { conn.info.request_count += 1; if !success { conn.info.error_count += 1; } conn.info.last_active = Self::current_timestamp(); // 更新统计 let mut stats = self.stats.lock().unwrap(); stats.total_requests += 1; if !success { stats.total_errors += 1; } Ok(()) } else { Err(NacLensError::NetworkError(format!( "Connection {} not found", conn_id ))) } } /// 获取连接信息 pub fn get_connection_info(&self, conn_id: &str) -> Option { let connections = self.connections.lock().unwrap(); connections.get(conn_id).map(|c| c.info.clone()) } /// 获取所有连接信息 pub fn get_all_connections(&self) -> Vec { let connections = self.connections.lock().unwrap(); connections.values().map(|c| c.info.clone()).collect() } /// 获取统计信息 pub fn get_stats(&self) -> PoolStats { let stats = self.stats.lock().unwrap(); stats.clone() } /// 获取配置 pub fn get_config(&self) -> &ConnectionConfig { &self.config } /// 获取当前时间戳 fn current_timestamp() -> u64 { std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs() } } /// 心跳管理器 #[derive(Debug)] pub struct HeartbeatManager { /// 连接池 pool: Arc, /// 心跳间隔 pub interval: Duration, /// 是否运行 running: Arc>, } impl HeartbeatManager { /// 创建新的心跳管理器 pub fn new(pool: Arc, interval: Duration) -> Self { Self { pool, interval, running: Arc::new(Mutex::new(false)), } } /// 启动心跳 pub fn start(&self) { let mut running = self.running.lock().unwrap(); *running = true; } /// 停止心跳 pub fn stop(&self) { let mut running = self.running.lock().unwrap(); *running = false; } /// 执行心跳检查 pub fn check(&self) { let running = self.running.lock().unwrap(); if !*running { return; } drop(running); // 检查心跳超时 let timeout_connections = self.pool.check_heartbeat_timeout(); for conn_id in timeout_connections { // 尝试重新连接或关闭 let _ = self.pool.close_connection(&conn_id); } // 清理空闲连接 let _ = self.pool.cleanup_idle_connections(); } /// 是否正在运行 pub fn is_running(&self) -> bool { let running = self.running.lock().unwrap(); *running } } #[cfg(test)] mod tests { use super::*; #[test] fn test_connection_pool_create() { let config = ConnectionConfig::default(); let pool = ConnectionPool::new(config); let stats = pool.get_stats(); assert_eq!(stats.total_connections, 0); } #[test] fn test_get_connection() { let config = ConnectionConfig::default(); let pool = ConnectionPool::new(config); let conn_id = pool.get_connection("127.0.0.1:8080").unwrap(); assert!(!conn_id.is_empty()); let info = pool.get_connection_info(&conn_id).unwrap(); assert_eq!(info.remote_addr, "127.0.0.1:8080"); assert_eq!(info.state, ConnectionState::Busy); } #[test] fn test_release_connection() { let config = ConnectionConfig::default(); let pool = ConnectionPool::new(config); let conn_id = pool.get_connection("127.0.0.1:8080").unwrap(); pool.release_connection(&conn_id).unwrap(); let info = pool.get_connection_info(&conn_id).unwrap(); assert_eq!(info.state, ConnectionState::Idle); } #[test] fn test_connection_reuse() { let mut config = ConnectionConfig::default(); config.enable_reuse = true; let pool = ConnectionPool::new(config); let conn_id1 = pool.get_connection("127.0.0.1:8080").unwrap(); pool.release_connection(&conn_id1).unwrap(); let conn_id2 = pool.get_connection("127.0.0.1:8080").unwrap(); assert_eq!(conn_id1, conn_id2); } #[test] fn test_close_connection() { let config = ConnectionConfig::default(); let pool = ConnectionPool::new(config); let conn_id = pool.get_connection("127.0.0.1:8080").unwrap(); pool.close_connection(&conn_id).unwrap(); assert!(pool.get_connection_info(&conn_id).is_none()); } #[test] fn test_record_request() { let config = ConnectionConfig::default(); let pool = ConnectionPool::new(config); let conn_id = pool.get_connection("127.0.0.1:8080").unwrap(); pool.record_request(&conn_id, true).unwrap(); pool.record_request(&conn_id, false).unwrap(); let info = pool.get_connection_info(&conn_id).unwrap(); assert_eq!(info.request_count, 2); assert_eq!(info.error_count, 1); let stats = pool.get_stats(); assert_eq!(stats.total_requests, 2); assert_eq!(stats.total_errors, 1); } #[test] fn test_heartbeat_manager() { let config = ConnectionConfig::default(); let pool = Arc::new(ConnectionPool::new(config)); let manager = HeartbeatManager::new(pool, Duration::from_secs(30)); assert!(!manager.is_running()); manager.start(); assert!(manager.is_running()); manager.stop(); assert!(!manager.is_running()); } }