Skip to main content

sz_rust_orm_facade/
pool_config.rs

1//! 连接池配置调优(L2 方案:sqlx 配置调优,不修改 sz-orm 上游)
2//!
3//! 提供 `SqlxPoolConfig` 便捷配置结构体,支持:
4//! - `Default`:与 sqlx 默认一致
5//! - `from_env()`:从环境变量读取
6//! - `for_high_concurrency()`:高并发预设
7//! - `for_low_latency()`:低延迟预设
8//! - `to_orm_pool_config()`:转换为 sz_orm_core::PoolConfig
9
10use std::time::Duration;
11
12use sz_orm_core::PoolConfig;
13
14/// sqlx 连接池配置(L2 调优层)
15///
16/// 不修改 sz-orm 上游,在 sz-rust-orm-facade 层提供便捷配置预设。
17#[derive(Debug, Clone)]
18pub struct SqlxPoolConfig {
19    /// 最大连接数
20    pub max_connections: u32,
21    /// 最小空闲连接数
22    pub min_connections: u32,
23    /// 获取连接超时
24    pub acquire_timeout: Duration,
25    /// 空闲连接超时
26    pub idle_timeout: Duration,
27    /// 连接最大生命周期
28    pub max_lifetime: Duration,
29}
30
31impl Default for SqlxPoolConfig {
32    fn default() -> Self {
33        Self {
34            max_connections: 10,
35            min_connections: 0,
36            acquire_timeout: Duration::from_secs(30),
37            idle_timeout: Duration::from_secs(600),
38            max_lifetime: Duration::from_secs(1800),
39        }
40    }
41}
42
43impl SqlxPoolConfig {
44    /// 从环境变量读取配置
45    ///
46    /// 环境变量:
47    /// - `DB_POOL_MAX`:最大连接数(默认 10)
48    /// - `DB_POOL_MIN`:最小空闲连接数(默认 0)
49    /// - `DB_POOL_ACQUIRE_TIMEOUT`:获取超时秒数(默认 30)
50    /// - `DB_POOL_IDLE_TIMEOUT`:空闲超时秒数(默认 600)
51    /// - `DB_POOL_MAX_LIFETIME`:最大生命周期秒数(默认 1800)
52    pub fn from_env() -> Self {
53        fn parse_env_u32(key: &str, default: u32) -> u32 {
54            std::env::var(key)
55                .ok()
56                .and_then(|v| v.parse().ok())
57                .unwrap_or(default)
58        }
59        fn parse_env_secs(key: &str, default: u64) -> Duration {
60            Duration::from_secs(parse_env_u32(key, default as u32) as u64)
61        }
62
63        Self {
64            max_connections: parse_env_u32("DB_POOL_MAX", 10),
65            min_connections: parse_env_u32("DB_POOL_MIN", 0),
66            acquire_timeout: parse_env_secs("DB_POOL_ACQUIRE_TIMEOUT", 30),
67            idle_timeout: parse_env_secs("DB_POOL_IDLE_TIMEOUT", 600),
68            max_lifetime: parse_env_secs("DB_POOL_MAX_LIFETIME", 1800),
69        }
70    }
71
72    /// 高并发预设:max=50, min=5, acquire=10s, idle=300s, max_lifetime=1800s
73    pub fn for_high_concurrency() -> Self {
74        Self {
75            max_connections: 50,
76            min_connections: 5,
77            acquire_timeout: Duration::from_secs(10),
78            idle_timeout: Duration::from_secs(300),
79            max_lifetime: Duration::from_secs(1800),
80        }
81    }
82
83    /// 低延迟预设:max=20, min=10, acquire=5s, idle=120s, max_lifetime=600s
84    pub fn for_low_latency() -> Self {
85        Self {
86            max_connections: 20,
87            min_connections: 10,
88            acquire_timeout: Duration::from_secs(5),
89            idle_timeout: Duration::from_secs(120),
90            max_lifetime: Duration::from_secs(600),
91        }
92    }
93
94    /// 转换为 sz_orm_core::PoolConfig
95    pub fn to_orm_pool_config(&self) -> PoolConfig {
96        PoolConfig {
97            max_size: self.max_connections,
98            min_idle: self.min_connections,
99            acquire_timeout: self.acquire_timeout,
100            idle_timeout: self.idle_timeout,
101            max_lifetime: self.max_lifetime,
102            ..Default::default()
103        }
104    }
105}
106
107#[cfg(test)]
108mod tests {
109    use super::*;
110
111    #[test]
112    fn test_pool_config_default() {
113        let config = SqlxPoolConfig::default();
114        assert_eq!(config.max_connections, 10);
115        assert_eq!(config.min_connections, 0);
116        assert_eq!(config.acquire_timeout, Duration::from_secs(30));
117        assert_eq!(config.idle_timeout, Duration::from_secs(600));
118        assert_eq!(config.max_lifetime, Duration::from_secs(1800));
119    }
120
121    #[test]
122    fn test_pool_config_from_env() {
123        std::env::set_var("DB_POOL_MAX", "42");
124        std::env::set_var("DB_POOL_MIN", "7");
125        std::env::set_var("DB_POOL_ACQUIRE_TIMEOUT", "15");
126        std::env::set_var("DB_POOL_IDLE_TIMEOUT", "200");
127        std::env::set_var("DB_POOL_MAX_LIFETIME", "900");
128
129        let config = SqlxPoolConfig::from_env();
130        assert_eq!(config.max_connections, 42);
131        assert_eq!(config.min_connections, 7);
132        assert_eq!(config.acquire_timeout, Duration::from_secs(15));
133        assert_eq!(config.idle_timeout, Duration::from_secs(200));
134        assert_eq!(config.max_lifetime, Duration::from_secs(900));
135
136        std::env::remove_var("DB_POOL_MAX");
137        std::env::remove_var("DB_POOL_MIN");
138        std::env::remove_var("DB_POOL_ACQUIRE_TIMEOUT");
139        std::env::remove_var("DB_POOL_IDLE_TIMEOUT");
140        std::env::remove_var("DB_POOL_MAX_LIFETIME");
141    }
142
143    #[test]
144    fn test_pool_config_high_concurrency() {
145        let config = SqlxPoolConfig::for_high_concurrency();
146        assert_eq!(config.max_connections, 50);
147        assert_eq!(config.min_connections, 5);
148        assert_eq!(config.acquire_timeout, Duration::from_secs(10));
149        assert_eq!(config.idle_timeout, Duration::from_secs(300));
150        assert_eq!(config.max_lifetime, Duration::from_secs(1800));
151    }
152
153    #[test]
154    fn test_pool_config_low_latency() {
155        let config = SqlxPoolConfig::for_low_latency();
156        assert_eq!(config.max_connections, 20);
157        assert_eq!(config.min_connections, 10);
158        assert_eq!(config.acquire_timeout, Duration::from_secs(5));
159        assert_eq!(config.idle_timeout, Duration::from_secs(120));
160        assert_eq!(config.max_lifetime, Duration::from_secs(600));
161    }
162
163    #[test]
164    fn test_pool_config_to_orm() {
165        let config = SqlxPoolConfig::for_high_concurrency();
166        let orm_config = config.to_orm_pool_config();
167        assert_eq!(orm_config.max_size, 50);
168        assert_eq!(orm_config.min_idle, 5);
169        assert_eq!(orm_config.acquire_timeout, Duration::from_secs(10));
170    }
171}