1use super::{ConnectionOptions, PoolOptions};
4use std::time::Duration;
5use tracing::info;
6
7#[derive(Debug, Clone)]
9pub struct PoolConfig {
10 pub connection: ConnectionOptions,
12 pub pool: PoolOptions,
14 pub retry_attempts: u32,
16 pub retry_delay: Duration,
18 pub health_check_interval: Option<Duration>,
20}
21
22impl Default for PoolConfig {
23 fn default() -> Self {
24 Self {
25 connection: ConnectionOptions::default(),
26 pool: PoolOptions::default(),
27 retry_attempts: 3,
28 retry_delay: Duration::from_millis(500),
29 health_check_interval: Some(Duration::from_secs(30)),
30 }
31 }
32}
33
34impl PoolConfig {
35 pub fn new() -> Self {
37 Self::default()
38 }
39
40 pub fn connection(mut self, options: ConnectionOptions) -> Self {
42 self.connection = options;
43 self
44 }
45
46 pub fn pool(mut self, options: PoolOptions) -> Self {
48 self.pool = options;
49 self
50 }
51
52 pub fn max_connections(mut self, n: u32) -> Self {
54 self.pool.max_connections = n;
55 self
56 }
57
58 pub fn min_connections(mut self, n: u32) -> Self {
60 self.pool.min_connections = n;
61 self
62 }
63
64 pub fn connect_timeout(mut self, timeout: Duration) -> Self {
66 self.connection.connect_timeout = timeout;
67 self
68 }
69
70 pub fn acquire_timeout(mut self, timeout: Duration) -> Self {
72 self.pool.acquire_timeout = timeout;
73 self
74 }
75
76 pub fn idle_timeout(mut self, timeout: Duration) -> Self {
78 self.pool.idle_timeout = Some(timeout);
79 self
80 }
81
82 pub fn max_lifetime(mut self, lifetime: Duration) -> Self {
84 self.pool.max_lifetime = Some(lifetime);
85 self
86 }
87
88 pub fn retry_attempts(mut self, attempts: u32) -> Self {
90 self.retry_attempts = attempts;
91 self
92 }
93
94 pub fn retry_delay(mut self, delay: Duration) -> Self {
96 self.retry_delay = delay;
97 self
98 }
99
100 pub fn health_check_interval(mut self, interval: Duration) -> Self {
102 self.health_check_interval = Some(interval);
103 self
104 }
105
106 pub fn no_health_check(mut self) -> Self {
108 self.health_check_interval = None;
109 self
110 }
111
112 pub fn low_latency() -> Self {
114 info!(
115 max_connections = 20,
116 min_connections = 5,
117 "PoolConfig::low_latency() initialized"
118 );
119 Self {
120 connection: ConnectionOptions::new().connect_timeout(Duration::from_secs(5)),
121 pool: PoolOptions::new()
122 .max_connections(20)
123 .min_connections(5)
124 .acquire_timeout(Duration::from_secs(5))
125 .idle_timeout(Duration::from_secs(60)),
126 retry_attempts: 1,
127 retry_delay: Duration::from_millis(100),
128 health_check_interval: Some(Duration::from_secs(10)),
129 }
130 }
131
132 pub fn high_throughput() -> Self {
134 info!(
135 max_connections = 50,
136 min_connections = 10,
137 "PoolConfig::high_throughput() initialized"
138 );
139 Self {
140 connection: ConnectionOptions::new().connect_timeout(Duration::from_secs(30)),
141 pool: PoolOptions::new()
142 .max_connections(50)
143 .min_connections(10)
144 .acquire_timeout(Duration::from_secs(30))
145 .idle_timeout(Duration::from_secs(300)),
146 retry_attempts: 3,
147 retry_delay: Duration::from_secs(1),
148 health_check_interval: Some(Duration::from_secs(60)),
149 }
150 }
151
152 pub fn development() -> Self {
154 info!(
155 max_connections = 5,
156 min_connections = 1,
157 "PoolConfig::development() initialized"
158 );
159 Self {
160 connection: ConnectionOptions::new().connect_timeout(Duration::from_secs(5)),
161 pool: PoolOptions::new()
162 .max_connections(5)
163 .min_connections(1)
164 .acquire_timeout(Duration::from_secs(5))
165 .test_before_acquire(false),
166 retry_attempts: 0,
167 retry_delay: Duration::from_millis(0),
168 health_check_interval: None,
169 }
170 }
171
172 pub fn read_heavy() -> Self {
179 info!(
180 max_connections = 30,
181 min_connections = 5,
182 "PoolConfig::read_heavy() initialized"
183 );
184 Self {
185 connection: ConnectionOptions::new().connect_timeout(Duration::from_secs(10)),
186 pool: PoolOptions::new()
187 .max_connections(30)
188 .min_connections(5)
189 .acquire_timeout(Duration::from_secs(15))
190 .idle_timeout(Duration::from_secs(300))
191 .max_lifetime(Duration::from_secs(3600)), retry_attempts: 2,
193 retry_delay: Duration::from_millis(200),
194 health_check_interval: Some(Duration::from_secs(30)),
195 }
196 }
197
198 pub fn write_heavy() -> Self {
205 info!(
206 max_connections = 15,
207 min_connections = 3,
208 "PoolConfig::write_heavy() initialized"
209 );
210 Self {
211 connection: ConnectionOptions::new().connect_timeout(Duration::from_secs(10)),
212 pool: PoolOptions::new()
213 .max_connections(15)
214 .min_connections(3)
215 .acquire_timeout(Duration::from_secs(20))
216 .idle_timeout(Duration::from_secs(120))
217 .max_lifetime(Duration::from_secs(900)), retry_attempts: 3,
219 retry_delay: Duration::from_millis(500),
220 health_check_interval: Some(Duration::from_secs(15)),
221 }
222 }
223
224 pub fn mixed_workload() -> Self {
228 info!(
229 max_connections = 25,
230 min_connections = 5,
231 "PoolConfig::mixed_workload() initialized"
232 );
233 Self {
234 connection: ConnectionOptions::new().connect_timeout(Duration::from_secs(10)),
235 pool: PoolOptions::new()
236 .max_connections(25)
237 .min_connections(5)
238 .acquire_timeout(Duration::from_secs(15))
239 .idle_timeout(Duration::from_secs(180))
240 .max_lifetime(Duration::from_secs(1800)), retry_attempts: 2,
242 retry_delay: Duration::from_millis(300),
243 health_check_interval: Some(Duration::from_secs(30)),
244 }
245 }
246
247 pub fn batch_processing() -> Self {
254 info!(
255 max_connections = 40,
256 min_connections = 10,
257 "PoolConfig::batch_processing() initialized"
258 );
259 Self {
260 connection: ConnectionOptions::new().connect_timeout(Duration::from_secs(30)),
261 pool: PoolOptions::new()
262 .max_connections(40)
263 .min_connections(10)
264 .acquire_timeout(Duration::from_secs(60))
265 .idle_timeout(Duration::from_secs(600))
266 .max_lifetime(Duration::from_secs(7200)), retry_attempts: 5,
268 retry_delay: Duration::from_secs(2),
269 health_check_interval: Some(Duration::from_secs(120)),
270 }
271 }
272
273 pub fn serverless() -> Self {
280 info!(
281 max_connections = 10,
282 min_connections = 0,
283 "PoolConfig::serverless() initialized"
284 );
285 Self {
286 connection: ConnectionOptions::new().connect_timeout(Duration::from_secs(3)),
287 pool: PoolOptions::new()
288 .max_connections(10)
289 .min_connections(0)
290 .acquire_timeout(Duration::from_secs(3))
291 .idle_timeout(Duration::from_secs(30))
292 .max_lifetime(Duration::from_secs(300)), retry_attempts: 1,
294 retry_delay: Duration::from_millis(50),
295 health_check_interval: None, }
297 }
298
299 pub fn for_workload(qps: u32, avg_query_ms: u32) -> Self {
316 let estimated_connections = ((qps * avg_query_ms) / 1000 + 1) * 120 / 100;
319 let max_connections = estimated_connections.clamp(5, 100);
320 let min_connections = (max_connections / 5).max(1);
321
322 Self {
323 connection: ConnectionOptions::new().connect_timeout(Duration::from_secs(10)),
324 pool: PoolOptions::new()
325 .max_connections(max_connections)
326 .min_connections(min_connections)
327 .acquire_timeout(Duration::from_secs(15))
328 .idle_timeout(Duration::from_secs(300)),
329 retry_attempts: 2,
330 retry_delay: Duration::from_millis(200),
331 health_check_interval: Some(Duration::from_secs(30)),
332 }
333 }
334}
335
336#[cfg(test)]
337mod tests {
338 use super::*;
339
340 #[test]
341 fn test_pool_config_builder() {
342 let config = PoolConfig::new()
343 .max_connections(30)
344 .min_connections(5)
345 .connect_timeout(Duration::from_secs(10))
346 .retry_attempts(5);
347
348 assert_eq!(config.pool.max_connections, 30);
349 assert_eq!(config.pool.min_connections, 5);
350 assert_eq!(config.connection.connect_timeout, Duration::from_secs(10));
351 assert_eq!(config.retry_attempts, 5);
352 }
353
354 #[test]
355 fn test_preset_configs() {
356 let low_latency = PoolConfig::low_latency();
357 assert_eq!(low_latency.pool.max_connections, 20);
358 assert_eq!(low_latency.retry_attempts, 1);
359
360 let high_throughput = PoolConfig::high_throughput();
361 assert_eq!(high_throughput.pool.max_connections, 50);
362
363 let dev = PoolConfig::development();
364 assert_eq!(dev.pool.max_connections, 5);
365 assert_eq!(dev.retry_attempts, 0);
366 }
367}