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()
121 .connect_timeout(Duration::from_secs(5)),
122 pool: PoolOptions::new()
123 .max_connections(20)
124 .min_connections(5)
125 .acquire_timeout(Duration::from_secs(5))
126 .idle_timeout(Duration::from_secs(60)),
127 retry_attempts: 1,
128 retry_delay: Duration::from_millis(100),
129 health_check_interval: Some(Duration::from_secs(10)),
130 }
131 }
132
133 pub fn high_throughput() -> Self {
135 info!(
136 max_connections = 50,
137 min_connections = 10,
138 "PoolConfig::high_throughput() initialized"
139 );
140 Self {
141 connection: ConnectionOptions::new()
142 .connect_timeout(Duration::from_secs(30)),
143 pool: PoolOptions::new()
144 .max_connections(50)
145 .min_connections(10)
146 .acquire_timeout(Duration::from_secs(30))
147 .idle_timeout(Duration::from_secs(300)),
148 retry_attempts: 3,
149 retry_delay: Duration::from_secs(1),
150 health_check_interval: Some(Duration::from_secs(60)),
151 }
152 }
153
154 pub fn development() -> Self {
156 info!(
157 max_connections = 5,
158 min_connections = 1,
159 "PoolConfig::development() initialized"
160 );
161 Self {
162 connection: ConnectionOptions::new()
163 .connect_timeout(Duration::from_secs(5)),
164 pool: PoolOptions::new()
165 .max_connections(5)
166 .min_connections(1)
167 .acquire_timeout(Duration::from_secs(5))
168 .test_before_acquire(false),
169 retry_attempts: 0,
170 retry_delay: Duration::from_millis(0),
171 health_check_interval: None,
172 }
173 }
174
175 pub fn read_heavy() -> Self {
182 info!(
183 max_connections = 30,
184 min_connections = 5,
185 "PoolConfig::read_heavy() initialized"
186 );
187 Self {
188 connection: ConnectionOptions::new()
189 .connect_timeout(Duration::from_secs(10)),
190 pool: PoolOptions::new()
191 .max_connections(30)
192 .min_connections(5)
193 .acquire_timeout(Duration::from_secs(15))
194 .idle_timeout(Duration::from_secs(300))
195 .max_lifetime(Duration::from_secs(3600)), retry_attempts: 2,
197 retry_delay: Duration::from_millis(200),
198 health_check_interval: Some(Duration::from_secs(30)),
199 }
200 }
201
202 pub fn write_heavy() -> Self {
209 info!(
210 max_connections = 15,
211 min_connections = 3,
212 "PoolConfig::write_heavy() initialized"
213 );
214 Self {
215 connection: ConnectionOptions::new()
216 .connect_timeout(Duration::from_secs(10)),
217 pool: PoolOptions::new()
218 .max_connections(15)
219 .min_connections(3)
220 .acquire_timeout(Duration::from_secs(20))
221 .idle_timeout(Duration::from_secs(120))
222 .max_lifetime(Duration::from_secs(900)), retry_attempts: 3,
224 retry_delay: Duration::from_millis(500),
225 health_check_interval: Some(Duration::from_secs(15)),
226 }
227 }
228
229 pub fn mixed_workload() -> Self {
233 info!(
234 max_connections = 25,
235 min_connections = 5,
236 "PoolConfig::mixed_workload() initialized"
237 );
238 Self {
239 connection: ConnectionOptions::new()
240 .connect_timeout(Duration::from_secs(10)),
241 pool: PoolOptions::new()
242 .max_connections(25)
243 .min_connections(5)
244 .acquire_timeout(Duration::from_secs(15))
245 .idle_timeout(Duration::from_secs(180))
246 .max_lifetime(Duration::from_secs(1800)), retry_attempts: 2,
248 retry_delay: Duration::from_millis(300),
249 health_check_interval: Some(Duration::from_secs(30)),
250 }
251 }
252
253 pub fn batch_processing() -> Self {
260 info!(
261 max_connections = 40,
262 min_connections = 10,
263 "PoolConfig::batch_processing() initialized"
264 );
265 Self {
266 connection: ConnectionOptions::new()
267 .connect_timeout(Duration::from_secs(30)),
268 pool: PoolOptions::new()
269 .max_connections(40)
270 .min_connections(10)
271 .acquire_timeout(Duration::from_secs(60))
272 .idle_timeout(Duration::from_secs(600))
273 .max_lifetime(Duration::from_secs(7200)), retry_attempts: 5,
275 retry_delay: Duration::from_secs(2),
276 health_check_interval: Some(Duration::from_secs(120)),
277 }
278 }
279
280 pub fn serverless() -> Self {
287 info!(
288 max_connections = 10,
289 min_connections = 0,
290 "PoolConfig::serverless() initialized"
291 );
292 Self {
293 connection: ConnectionOptions::new()
294 .connect_timeout(Duration::from_secs(3)),
295 pool: PoolOptions::new()
296 .max_connections(10)
297 .min_connections(0)
298 .acquire_timeout(Duration::from_secs(3))
299 .idle_timeout(Duration::from_secs(30))
300 .max_lifetime(Duration::from_secs(300)), retry_attempts: 1,
302 retry_delay: Duration::from_millis(50),
303 health_check_interval: None, }
305 }
306
307 pub fn for_workload(qps: u32, avg_query_ms: u32) -> Self {
324 let estimated_connections = ((qps * avg_query_ms) / 1000 + 1) * 120 / 100;
327 let max_connections = estimated_connections.clamp(5, 100) as u32;
328 let min_connections = (max_connections / 5).max(1);
329
330 Self {
331 connection: ConnectionOptions::new()
332 .connect_timeout(Duration::from_secs(10)),
333 pool: PoolOptions::new()
334 .max_connections(max_connections)
335 .min_connections(min_connections)
336 .acquire_timeout(Duration::from_secs(15))
337 .idle_timeout(Duration::from_secs(300)),
338 retry_attempts: 2,
339 retry_delay: Duration::from_millis(200),
340 health_check_interval: Some(Duration::from_secs(30)),
341 }
342 }
343}
344
345#[cfg(test)]
346mod tests {
347 use super::*;
348
349 #[test]
350 fn test_pool_config_builder() {
351 let config = PoolConfig::new()
352 .max_connections(30)
353 .min_connections(5)
354 .connect_timeout(Duration::from_secs(10))
355 .retry_attempts(5);
356
357 assert_eq!(config.pool.max_connections, 30);
358 assert_eq!(config.pool.min_connections, 5);
359 assert_eq!(config.connection.connect_timeout, Duration::from_secs(10));
360 assert_eq!(config.retry_attempts, 5);
361 }
362
363 #[test]
364 fn test_preset_configs() {
365 let low_latency = PoolConfig::low_latency();
366 assert_eq!(low_latency.pool.max_connections, 20);
367 assert_eq!(low_latency.retry_attempts, 1);
368
369 let high_throughput = PoolConfig::high_throughput();
370 assert_eq!(high_throughput.pool.max_connections, 50);
371
372 let dev = PoolConfig::development();
373 assert_eq!(dev.pool.max_connections, 5);
374 assert_eq!(dev.retry_attempts, 0);
375 }
376}
377
378