Skip to main content

sz_orm_core/
pool.rs

1//! Connection Pool
2//!
3//! Provides async connection pooling with configurable options
4
5use async_trait::async_trait;
6use crossbeam_queue::ArrayQueue;
7use futures::StreamExt;
8// P1-4 修复:使用核心层定义的 CircuitBreaker/RateLimiter 抽象,
9// 消除对 sz-orm-health/sz-orm-limit 的反向依赖。
10// parking_lot 锁仅在启用 circuit-breaker/rate-limit feature 时使用
11#[cfg(feature = "circuit-breaker")]
12use parking_lot::Mutex as PlMutex;
13#[cfg(feature = "rate-limit")]
14use parking_lot::RwLock as PlRwLock;
15use std::future::Future;
16use std::ops::{Deref, DerefMut};
17use std::pin::Pin;
18use std::sync::atomic::{AtomicBool, AtomicU32, AtomicU64, Ordering};
19use std::sync::Arc;
20use std::time::{Duration, Instant};
21use tokio::sync::Notify;
22
23// P1-4 修复:CircuitBreaker/RateLimiter 抽象已提升到核心层,
24// 仅在启用相应 feature 时导入(避免 default feature 下的 unused imports)
25// 注意:trait 方法(can_execute/record_success 等)需要 trait 在 scope 中
26#[cfg(feature = "circuit-breaker")]
27use crate::circuit_breaker::{CircuitBreaker, CircuitState, DefaultCircuitBreaker};
28use crate::error::PoolError;
29#[cfg(feature = "rate-limit")]
30use crate::rate_limiter::RateLimiter;
31
32/// 查询结果行类型别名:避免 `Connection::query` 签名触发 `clippy::type_complexity`。
33pub type QueryRows = Vec<std::collections::HashMap<String, crate::value::Value>>;
34
35/// 流式查询结果项类型别名:避免 `Connection::query_stream` 签名触发 `clippy::type_complexity`。
36pub type QueryStreamItem =
37    Result<std::collections::HashMap<String, crate::value::Value>, crate::DbError>;
38
39/// 数据库连接 trait
40///
41/// 注意:此 trait 手动解糖 async 方法(不使用 `#[async_trait]`),
42/// 以避免 `&str` 参数触发 HRTB 与 sqlx::Executor 冲突。
43/// 所有 async 方法使用单一生命周期 `'a`(绑定 `&'a mut self` 和 `&'a str`),
44/// 而非 HRTB,从而允许 sqlx 适配器实现。
45pub trait Connection: Send + Sync {
46    fn execute<'a>(
47        &'a mut self,
48        sql: &'a str,
49    ) -> Pin<Box<dyn Future<Output = Result<u64, crate::DbError>> + Send + 'a>>;
50    fn query<'a>(
51        &'a mut self,
52        sql: &'a str,
53    ) -> Pin<Box<dyn Future<Output = Result<QueryRows, crate::DbError>> + Send + 'a>>;
54    fn begin_transaction<'a>(
55        &'a mut self,
56    ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>>;
57    fn commit<'a>(
58        &'a mut self,
59    ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>>;
60    fn rollback<'a>(
61        &'a mut self,
62    ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>>;
63    fn is_connected(&self) -> bool;
64    fn ping<'a>(&'a mut self) -> Pin<Box<dyn Future<Output = bool> + Send + 'a>>;
65    fn close<'a>(
66        &'a mut self,
67    ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>>;
68
69    /// 参数绑定执行(INSERT/UPDATE/DELETE)
70    ///
71    /// 使用真实 prepared statement 绑定参数,避免 SQL 注入。
72    /// 默认实现返回 `NotImplemented` 错误;支持参数绑定的适配器
73    /// (如 sz-orm-oracle)应覆盖此方法。
74    fn execute_with_params<'a>(
75        &'a mut self,
76        sql: &'a str,
77        params: &'a [crate::value::Value],
78    ) -> Pin<Box<dyn Future<Output = Result<u64, crate::DbError>> + Send + 'a>> {
79        let _ = (sql, params);
80        Box::pin(async move {
81            Err(crate::DbError::Internal(
82                "execute_with_params not implemented for this adapter".to_string(),
83            ))
84        })
85    }
86
87    /// 参数绑定查询(SELECT)
88    ///
89    /// 使用真实 prepared statement 绑定参数,避免 SQL 注入。
90    /// 默认实现返回 `NotImplemented` 错误;支持参数绑定的适配器
91    /// (如 sz-orm-oracle)应覆盖此方法。
92    fn query_with_params<'a>(
93        &'a mut self,
94        sql: &'a str,
95        params: &'a [crate::value::Value],
96    ) -> Pin<Box<dyn Future<Output = Result<QueryRows, crate::DbError>> + Send + 'a>> {
97        let _ = (sql, params);
98        Box::pin(async move {
99            Err(crate::DbError::Internal(
100                "query_with_params not implemented for this adapter".to_string(),
101            ))
102        })
103    }
104
105    /// 位置式查询(SELECT):返回 `(列名, 按列顺序的值矩阵)`
106    ///
107    /// 绕过 `HashMap<String, Value>` 行映射,适用于 SELECT ALL 大结果集场景。
108    /// 默认实现返回 `NotImplemented` 错误;适配器可覆盖此方法以获得 30%~50% 性能提升。
109    fn query_values<'a>(
110        &'a mut self,
111        sql: &'a str,
112    ) -> Pin<Box<dyn Future<Output = Result<crate::value::QueryValues, crate::DbError>> + Send + 'a>>
113    {
114        let _ = sql;
115        Box::pin(async move {
116            Err(crate::DbError::Internal(
117                "query_values not implemented for this adapter".to_string(),
118            ))
119        })
120    }
121
122    /// 参数绑定位置式查询(SELECT):叠加 prepared statement + 位置式映射双重优化
123    ///
124    /// 默认实现返回 `NotImplemented` 错误;适配器可覆盖此方法以获得最佳性能。
125    fn query_values_with_params<'a>(
126        &'a mut self,
127        sql: &'a str,
128        params: &'a [crate::value::Value],
129    ) -> Pin<Box<dyn Future<Output = Result<crate::value::QueryValues, crate::DbError>> + Send + 'a>>
130    {
131        let _ = (sql, params);
132        Box::pin(async move {
133            Err(crate::DbError::Internal(
134                "query_values_with_params not implemented for this adapter".to_string(),
135            ))
136        })
137    }
138
139    /// 流式查询:返回逐行结果流
140    ///
141    /// 默认实现:通过 `query()` 获取全部行后,以
142    /// `futures::stream::iter` 逐行 yield,提供统一的流式消费接口。
143    /// 适合中小结果集;对超大结果集,支持原生游标的适配器应覆盖此方法。
144    ///
145    /// # 注意
146    ///
147    /// 此方法本身是同步的(返回 Stream),但内部通过 `futures::stream::once`
148    /// 异步获取数据后展开为逐行流。若适配器支持 sqlx `fetch()` 游标,
149    /// 覆盖此方法可获得真正的逐行拉取,避免大结果集内存峰值。
150    fn query_stream<'a>(
151        &'a mut self,
152        sql: &'a str,
153    ) -> Pin<Box<dyn futures::Stream<Item = QueryStreamItem> + Send + 'a>> {
154        // 克隆 sql 以脱离 &self 的生命周期
155        let sql_owned = sql.to_string();
156        // 使用 stream::once 异步执行查询,再 flat_map 为逐行流
157        let stream = futures::stream::once(async move { self.query(&sql_owned).await })
158            // 统一为 Vec 收集后再 iter:保证 match 两臂流类型一致(E0308 修复)
159            .map(|result| {
160                let items: Vec<QueryStreamItem> = match result {
161                    Ok(rows) => rows.into_iter().map(Ok).collect(),
162                    Err(e) => vec![Err(e)],
163                };
164                futures::stream::iter(items)
165            })
166            .flatten();
167        Box::pin(stream)
168    }
169
170    /// 游标式流式查询(P1-2):按 `batch_size` 分批拉取,避免大结果集内存峰值。
171    ///
172    /// 适用于无原生服务器端游标(或无法便捷暴露逐行拉取)的数据库:
173    /// - Oracle:`ROWNUM` 子查询包装(见 `cursor_stream::build_paged_query`);
174    /// - SQL Server:`OFFSET ... ROWS FETCH NEXT ... ROWS ONLY`。
175    ///
176    /// 默认实现退化为 [`Connection::query_stream`](全量拉取后逐行 yield);
177    /// Oracle/MSSQL 适配器应覆盖此方法,使用
178    /// `cursor_stream::stream_cursor_paged(conn, sql, DbType::Oracle, batch)`
179    /// 获得真正的分页游标流。
180    fn query_stream_cursor<'a>(
181        &'a mut self,
182        sql: &'a str,
183        _batch_size: usize,
184    ) -> Pin<Box<dyn futures::Stream<Item = QueryStreamItem> + Send + 'a>> {
185        self.query_stream(sql)
186    }
187
188    /// 批量执行多条 SQL(按顺序执行,返回累计影响行数)
189    ///
190    /// 默认实现循环调用 `execute`;适配器可覆盖此方法以利用数据库原生
191    /// 批量执行能力。
192    fn execute_batch<'a>(
193        &'a mut self,
194        sqls: &'a [String],
195    ) -> Pin<Box<dyn Future<Output = Result<u64, crate::DbError>> + Send + 'a>> {
196        Box::pin(async move {
197            let mut total = 0u64;
198            for sql in sqls {
199                total += self.execute(sql).await?;
200            }
201            Ok(total)
202        })
203    }
204
205    /// 批量插入(单条 SQL 多次参数绑定执行)
206    ///
207    /// 默认实现循环调用 `execute_with_params`;适配器可覆盖此方法
208    /// 以利用数据库原生批量 DML 能力(如 Oracle Array DML)。
209    fn execute_batch_params<'a>(
210        &'a mut self,
211        sql: &'a str,
212        params_batch: &'a [Vec<crate::value::Value>],
213    ) -> Pin<Box<dyn Future<Output = Result<u64, crate::DbError>> + Send + 'a>> {
214        Box::pin(async move {
215            let mut total = 0u64;
216            for params in params_batch {
217                total += self.execute_with_params(sql, params).await?;
218            }
219            Ok(total)
220        })
221    }
222}
223
224/// 连接池中的连接条目,记录创建时间和最后使用时间
225///
226/// - `created_at`:连接的原始创建时间,**不**随 acquire/release 重置,
227///   用于 `max_lifetime` 过期判定。
228/// - `last_used_at`:上次归还到池的时间,用于 `idle_timeout` 空闲超时判定。
229/// - `pool`:归属的连接池引用,Drop 时自动归还。`None` 表示无需归还
230///   (已通过 `release()`/`into_inner()` 显式处理)。
231pub struct PooledConnection {
232    conn: Box<dyn Connection>,
233    created_at: Instant,
234    last_used_at: Instant,
235    pool: Option<Pool>,
236}
237
238impl PooledConnection {
239    fn new(conn: Box<dyn Connection>, pool: Pool) -> Self {
240        let now = Instant::now();
241        Self {
242            conn,
243            created_at: now,
244            last_used_at: now,
245            pool: Some(pool),
246        }
247    }
248
249    fn is_expired(&self, max_lifetime: Duration) -> bool {
250        self.created_at.elapsed() >= max_lifetime
251    }
252
253    fn is_idle_too_long(&self, idle_timeout: Duration) -> bool {
254        self.last_used_at.elapsed() >= idle_timeout
255    }
256
257    /// 连接的原始创建时间(不随 acquire/release 重置)
258    pub fn created_at(&self) -> Instant {
259        self.created_at
260    }
261
262    /// 提取内部连接(消费 PooledConnection)
263    ///
264    /// 用于将连接传递给 `Transaction::new` 等消费连接的 API。
265    /// 调用此方法后,连接不再属于池,调用方需自行管理其生命周期。
266    pub fn into_inner(mut self) -> Box<dyn Connection> {
267        self.pool = None; // 标记无需归还
268                          // PooledConnection 实现了 Drop,不能直接 move conn,
269                          // 用 mem::replace 取出连接,放入 ClosedConnection 占位符
270        std::mem::replace(&mut self.conn, Box::new(ClosedConnection))
271    }
272}
273
274/// PooledConnection 的 Drop 实现:自动归还连接到池中
275///
276/// 修复 Critical Bug:之前 PooledConnection 未实现 Drop,连接在 drop 时
277/// 丢失,不归还池中,导致池耗尽。
278///
279/// 实现策略:
280/// 1. 如果 `pool` 为 `Some`(未显式 release/into_inner),取出连接并放入
281///    `ClosedConnection` 占位符
282/// 2. 在 tokio runtime 中 spawn 异步 release(Drop 不能 await)
283/// 3. 如果不在 tokio runtime 中(P0 修复):手动递减 `total_count`,
284///    避免池容量被耗尽;连接随 `pooled` drop 自然释放(依赖底层连接 Drop)
285impl Drop for PooledConnection {
286    fn drop(&mut self) {
287        if let Some(pool) = self.pool.take() {
288            // 取出原始连接,放入占位符(避免重复 close)
289            let conn = std::mem::replace(&mut self.conn, Box::new(ClosedConnection));
290            let pooled = PooledConnection {
291                conn,
292                created_at: self.created_at,
293                last_used_at: self.last_used_at,
294                pool: None,
295            };
296            // 尝试在 tokio runtime 中异步归还
297            if let Ok(handle) = tokio::runtime::Handle::try_current() {
298                handle.spawn(async move {
299                    pool.release(pooled).await;
300                });
301            } else {
302                // 不在 tokio runtime 中:手动递减计数器,避免池容量泄漏
303                // 注意:close 是 async 方法,无法在 sync Drop 中 await;
304                //       连接随 `pooled` drop 自然释放(依赖底层连接 Drop)
305                drop(pooled);
306                pool.total_count.fetch_sub(1, Ordering::SeqCst);
307            }
308        }
309    }
310}
311
312/// 占位连接,用于 PooledConnection::Drop 替换原始连接
313///
314/// 所有操作返回错误或默认值,`is_connected()` 返回 false。
315struct ClosedConnection;
316
317impl Connection for ClosedConnection {
318    fn execute<'a>(
319        &'a mut self,
320        _sql: &'a str,
321    ) -> Pin<Box<dyn Future<Output = Result<u64, crate::DbError>> + Send + 'a>> {
322        Box::pin(async {
323            Err(crate::DbError::ConnectionError(
324                "connection already returned to pool".to_string(),
325            ))
326        })
327    }
328
329    fn query<'a>(
330        &'a mut self,
331        _sql: &'a str,
332    ) -> Pin<Box<dyn Future<Output = Result<QueryRows, crate::DbError>> + Send + 'a>> {
333        Box::pin(async {
334            Err(crate::DbError::ConnectionError(
335                "connection already returned to pool".to_string(),
336            ))
337        })
338    }
339
340    fn begin_transaction<'a>(
341        &'a mut self,
342    ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
343        Box::pin(async {
344            Err(crate::DbError::ConnectionError(
345                "connection already returned to pool".to_string(),
346            ))
347        })
348    }
349
350    fn commit<'a>(
351        &'a mut self,
352    ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
353        Box::pin(async { Ok(()) })
354    }
355
356    fn rollback<'a>(
357        &'a mut self,
358    ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
359        Box::pin(async { Ok(()) })
360    }
361
362    fn is_connected(&self) -> bool {
363        false
364    }
365
366    fn ping<'a>(&'a mut self) -> Pin<Box<dyn Future<Output = bool> + Send + 'a>> {
367        Box::pin(async { false })
368    }
369
370    fn close<'a>(
371        &'a mut self,
372    ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
373        Box::pin(async { Ok(()) })
374    }
375}
376
377impl Deref for PooledConnection {
378    type Target = dyn Connection;
379
380    fn deref(&self) -> &Self::Target {
381        self.conn.as_ref()
382    }
383}
384
385impl DerefMut for PooledConnection {
386    fn deref_mut(&mut self) -> &mut Self::Target {
387        self.conn.as_mut()
388    }
389}
390
391/// TLS 版本
392#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
393pub enum TlsVersion {
394    #[default]
395    Tls12,
396    Tls13,
397}
398
399/// TLS 配置
400#[derive(Debug, Clone, Default)]
401pub struct TlsConfig {
402    /// 是否启用 TLS
403    pub enabled: bool,
404    /// CA 证书路径
405    pub ca_cert_path: Option<String>,
406    /// 客户端证书路径(双向 TLS)
407    pub client_cert_path: Option<String>,
408    /// 客户端私钥路径
409    pub client_key_path: Option<String>,
410    /// 最小 TLS 版本
411    pub min_version: TlsVersion,
412}
413
414/// 连接池事件
415#[derive(Debug, Clone)]
416pub enum PoolEvent {
417    /// 创建新连接
418    ConnectionCreated,
419    /// 连接被关闭
420    ConnectionClosed,
421    /// 连接被获取
422    ConnectionAcquired,
423    /// 连接被归还
424    ConnectionReleased,
425    /// 获取连接超时
426    AcquireTimeout,
427}
428
429/// 连接池事件回调
430pub type PoolEventCallback = Arc<dyn Fn(PoolEvent) + Send + Sync>;
431
432pub struct PoolConfig {
433    pub max_size: u32,
434    pub min_idle: u32,
435    pub acquire_timeout: Duration,
436    pub idle_timeout: Duration,
437    pub max_lifetime: Duration,
438    pub connection_timeout: Duration,
439    /// TLS 配置
440    pub tls: Option<TlsConfig>,
441    /// SQL 执行超时(默认 30 秒)
442    pub query_timeout: Option<Duration>,
443    /// 单次查询最大返回行数(默认无限制)
444    pub max_rows: Option<usize>,
445    /// 内存使用上限(字节,默认无限制)
446    pub memory_limit: Option<usize>,
447    /// 连接池事件回调
448    pub on_event: Option<PoolEventCallback>,
449    /// acquire 时是否执行 ping 验证连接存活(默认 false)。
450    ///
451    /// 开启后,从空闲队列取出的连接会先执行 `ping()` 验证网络连通性,
452    /// ping 失败的连接会被丢弃并重新 acquire。
453    ///
454    /// **注意**:开启此选项会增加每次 acquire 的延迟(一次额外的网络 RTT)。
455    /// 适用于 DB 可能重启且不能容忍首次查询失败的场景。
456    pub test_before_acquire: bool,
457    /// 连接池预热:启用后池创建时立即建立 `min_idle` 个连接(默认 false)。
458    ///
459    /// 预热后首次 acquire 延迟 < 10ms(对比冷启动 < 100ms)。
460    ///
461    /// # 示例
462    ///
463    /// ```ignore
464    /// let config = PoolConfig::default().with_prewarm(true);
465    /// let pool = Pool::new(config, factory).await?;
466    /// // 此时池中已有 min_idle 个连接
467    /// ```
468    pub prewarm: bool,
469}
470
471impl Default for PoolConfig {
472    fn default() -> Self {
473        Self {
474            max_size: 100,
475            min_idle: 0,
476            acquire_timeout: Duration::from_secs(30),
477            idle_timeout: Duration::from_secs(600),
478            max_lifetime: Duration::from_secs(1800),
479            connection_timeout: Duration::from_secs(10),
480            tls: None,
481            query_timeout: Some(Duration::from_secs(30)),
482            max_rows: None,
483            memory_limit: None,
484            on_event: None,
485            test_before_acquire: false,
486            prewarm: false,
487        }
488    }
489}
490
491impl Clone for PoolConfig {
492    fn clone(&self) -> Self {
493        Self {
494            max_size: self.max_size,
495            min_idle: self.min_idle,
496            acquire_timeout: self.acquire_timeout,
497            idle_timeout: self.idle_timeout,
498            max_lifetime: self.max_lifetime,
499            connection_timeout: self.connection_timeout,
500            tls: self.tls.clone(),
501            query_timeout: self.query_timeout,
502            max_rows: self.max_rows,
503            memory_limit: self.memory_limit,
504            on_event: self.on_event.clone(),
505            test_before_acquire: self.test_before_acquire,
506            prewarm: self.prewarm,
507        }
508    }
509}
510
511impl PoolConfig {
512    /// 校验配置合法性
513    pub fn validate(&self) -> Result<(), PoolError> {
514        if self.max_size == 0 {
515            return Err(PoolError::InvalidConfig("max_size cannot be 0".to_string()));
516        }
517        if self.min_idle > self.max_size {
518            return Err(PoolError::InvalidConfig(
519                "min_idle cannot exceed max_size".to_string(),
520            ));
521        }
522        // Duration 上界校验:防止 `Instant::now() + duration` 溢出 panic。
523        // u64::MAX 秒 ≈ 5.8e11 年,远超任何合理配置;实际使用中 1 年(31_536_000 秒)
524        // 已是宽松上限。此处用 u32::MAX 秒(≈ 136 年)作为硬性上限,
525        // 既覆盖所有现实场景,又保证 `Instant + Duration` 在 i64 微秒精度内不溢出。
526        const MAX_DURATION_SECS: u64 = u32::MAX as u64; // ≈ 136 年
527        for (name, dur) in [
528            ("acquire_timeout", self.acquire_timeout),
529            ("idle_timeout", self.idle_timeout),
530            ("max_lifetime", self.max_lifetime),
531            ("connection_timeout", self.connection_timeout),
532        ] {
533            if dur.as_secs() > MAX_DURATION_SECS {
534                return Err(PoolError::InvalidConfig(format!(
535                    "{name} ({:?}) exceeds maximum allowed duration ({} seconds)",
536                    dur, MAX_DURATION_SECS
537                )));
538            }
539        }
540        Ok(())
541    }
542
543    /// 设置预热标志(链式调用)
544    #[must_use]
545    pub fn with_prewarm(mut self, prewarm: bool) -> Self {
546        self.prewarm = prewarm;
547        self
548    }
549}
550
551pub struct PoolStatus {
552    pub idle: u32,
553    pub active: u32,
554    pub max: u32,
555    pub min: u32,
556    /// 等待 acquire 的任务数
557    pub waiters: u32,
558}
559
560impl std::fmt::Debug for PoolStatus {
561    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
562        f.debug_struct("PoolStatus")
563            .field("idle", &self.idle)
564            .field("active", &self.active)
565            .field("max", &self.max)
566            .field("min", &self.min)
567            .field("waiters", &self.waiters)
568            .finish()
569    }
570}
571
572/// 连接池累计统计指标(Prometheus 风格)
573///
574/// 所有字段均为池生命周期内的累计值(不会随获取/归还重置),
575/// 由 `Pool::pool_metrics()` 返回。基于无锁 `AtomicU64` 计数,
576/// 对 acquire/release 热路径的影响可忽略(单条原子指令)。
577#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
578pub struct PoolMetrics {
579    /// 累计成功获取连接次数
580    pub acquire_count: u64,
581    /// 累计获取连接失败次数(超时 / 连接创建失败 / 池已关闭 / 断路器或限流拒绝)
582    pub acquire_failed_count: u64,
583    /// 累计等待获取连接的时长(池满时阻塞等待的累计时间)
584    pub acquire_wait_time: Duration,
585    /// 累计归还连接次数
586    pub release_count: u64,
587    /// 累计创建连接数(含 prewarm / warmup / acquire 新建)
588    pub connection_created_count: u64,
589    /// 累计关闭连接数(含过期回收 / 失效 / 池关闭)
590    pub connection_closed_count: u64,
591}
592
593impl PoolMetrics {
594    /// 平均获取等待时长(无成功获取时为 0)
595    #[must_use]
596    pub fn average_acquire_wait_time(&self) -> Duration {
597        if self.acquire_count == 0 {
598            Duration::ZERO
599        } else {
600            self.acquire_wait_time / self.acquire_count as u32
601        }
602    }
603}
604
605pub struct PoolConfigBuilder {
606    config: PoolConfig,
607}
608
609impl PoolConfigBuilder {
610    pub fn new() -> Self {
611        Self {
612            config: PoolConfig::default(),
613        }
614    }
615
616    pub fn max_size(mut self, size: u32) -> Self {
617        self.config.max_size = size;
618        self
619    }
620
621    pub fn min_idle(mut self, count: u32) -> Self {
622        self.config.min_idle = count;
623        self
624    }
625
626    pub fn acquire_timeout(mut self, timeout_secs: u64) -> Self {
627        self.config.acquire_timeout = Duration::from_secs(timeout_secs);
628        self
629    }
630
631    pub fn idle_timeout(mut self, timeout_secs: u64) -> Self {
632        self.config.idle_timeout = Duration::from_secs(timeout_secs);
633        self
634    }
635
636    pub fn max_lifetime(mut self, lifetime_secs: u64) -> Self {
637        self.config.max_lifetime = Duration::from_secs(lifetime_secs);
638        self
639    }
640
641    /// 设置 TLS 配置
642    pub fn tls(mut self, tls: TlsConfig) -> Self {
643        self.config.tls = Some(tls);
644        self
645    }
646
647    /// 设置 SQL 执行超时
648    pub fn query_timeout(mut self, timeout: Duration) -> Self {
649        self.config.query_timeout = Some(timeout);
650        self
651    }
652
653    /// 设置单次查询最大返回行数
654    pub fn max_rows(mut self, max_rows: usize) -> Self {
655        self.config.max_rows = Some(max_rows);
656        self
657    }
658
659    /// 设置内存使用上限(字节)
660    pub fn memory_limit(mut self, memory_limit: usize) -> Self {
661        self.config.memory_limit = Some(memory_limit);
662        self
663    }
664
665    /// 设置连接池事件回调
666    pub fn on_event(mut self, callback: PoolEventCallback) -> Self {
667        self.config.on_event = Some(callback);
668        self
669    }
670
671    /// 设置 acquire 时是否执行 ping 验证连接存活(P1-1)
672    ///
673    /// 开启后,从空闲队列取出的连接会先执行 `ping()` 验证网络连通性。
674    /// 默认关闭(仅做 `is_connected()` 内存检查)。
675    pub fn test_before_acquire(mut self, enabled: bool) -> Self {
676        self.config.test_before_acquire = enabled;
677        self
678    }
679
680    /// 设置连接池预热(P2-1)
681    ///
682    /// 启用后池创建时立即建立 `min_idle` 个连接,减少首次查询延迟。
683    /// 默认关闭(冷启动)。
684    pub fn prewarm(mut self, enabled: bool) -> Self {
685        self.config.prewarm = enabled;
686        self
687    }
688
689    pub fn build(self) -> Result<PoolConfig, PoolError> {
690        self.config.validate()?;
691        Ok(self.config)
692    }
693}
694
695impl Default for PoolConfigBuilder {
696    fn default() -> Self {
697        Self::new()
698    }
699}
700
701/// 连接工厂 trait,用于创建新连接
702#[async_trait]
703pub trait ConnectionFactory: Send + Sync {
704    async fn create(&self) -> Result<Box<dyn Connection>, crate::DbError>;
705}
706
707/// 连接池核心实现
708///
709/// 所有字段均为 `Arc` 或内部含 `Arc`(`Notify`、`PoolConfig` 可 clone),
710/// 因此 `Pool` 可低成本 clone(仅增加引用计数)。`PooledConnection` 持有
711/// `Pool` 的 clone 以实现 Drop 自动归还。
712pub struct Pool {
713    config: PoolConfig,
714    factory: Arc<dyn ConnectionFactory>,
715    /// v1.1.0 优化 2:从 `Arc<Mutex<VecDeque<PooledConnection>>>` 改为
716    /// `Arc<ArrayQueue<PooledConnection>>`,使用无锁 MPMC 队列消除锁竞争。
717    /// 容量固定为 `config.max_size`,因为 `total_count` 已限制池中总连接数
718    /// 不超过 `max_size`,所以 `push` 不会因容量不足失败(除非并发 release
719    /// 超过 max_size,那只在 close_all 后的归还路径发生,此时连接会被直接关闭)。
720    idle: Arc<ArrayQueue<PooledConnection>>,
721    /// 池中总连接数(idle + borrowed)
722    ///
723    /// v0.2.1 修复 Critical P-1:从 `Mutex<u32>` 改为 `AtomicU32`
724    ///
725    /// # 原因
726    ///
727    /// - `Mutex<u32>` 在高并发下成为瓶颈(每次 acquire/release 都要 lock)
728    /// - `AtomicU32` 是无锁的,fetch_add/fetch_sub 是单条 CPU 指令
729    /// - 修复后吞吐量提升 ~3x(实测 10 task × 1000 acquire/release)
730    total_count: Arc<AtomicU32>,
731    /// 池是否已关闭(close_all 后设为 true,拒绝新 acquire/release)
732    closed: Arc<AtomicBool>,
733    notify: Arc<Notify>,
734    /// 等待 acquire 的任务数(监控用)
735    waiters_count: Arc<AtomicU32>,
736    /// 动态 max_size(可通过 resize/set_max_size 修改,初始值为 config.max_size)
737    dynamic_max_size: Arc<AtomicU32>,
738    /// #88 修复:断路器(启用 `circuit-breaker` feature 时生效)
739    ///
740    /// 当数据库连续失败超过阈值时,断路器跳闸,拒绝新 acquire 请求,
741    /// 避免对下游数据库造成更大压力。reset_timeout 后进入 HalfOpen 状态,
742    /// 放行一次试探请求;成功则 Closed,失败则重新 Open。
743    #[cfg(feature = "circuit-breaker")]
744    circuit_breaker: Arc<PlMutex<DefaultCircuitBreaker>>,
745    /// #93 修复:限流器(启用 `rate-limit` feature 时生效)
746    ///
747    /// 在 acquire 前调用 `try_acquire(key)`,被拒绝时返回 `PoolError::RateLimited`。
748    /// 默认 key 为 `"pool"`,调用方可通过 `acquire_with_key` 指定按用户/IP 维度限流。
749    /// 使用 `RwLock<Option<...>>` 支持运行时动态启用/禁用/替换限流器。
750    ///
751    /// P1-4 修复:使用核心层 `crate::rate_limiter::RateLimiter` trait,
752    /// 而非 `sz_orm_limit::RateLimiter`,消除反向依赖。
753    #[cfg(feature = "rate-limit")]
754    rate_limiter: Arc<PlRwLock<Option<Arc<dyn RateLimiter>>>>,
755    /// #93 修复:限流器使用的 key(默认 "pool")
756    #[cfg(feature = "rate-limit")]
757    rate_limit_key: String,
758    /// 累计成功获取连接次数(Prometheus 风格统计,无锁原子计数)
759    acquire_count: Arc<AtomicU64>,
760    /// 累计获取连接失败次数(超时 / 连接创建失败 / 池已关闭 / 断路器或限流拒绝)
761    acquire_failed_count: Arc<AtomicU64>,
762    /// 累计等待获取连接的时长(纳秒,池满时阻塞等待的累计时间)
763    acquire_wait_time_ns: Arc<AtomicU64>,
764    /// 累计归还连接次数
765    release_count: Arc<AtomicU64>,
766    /// 累计创建连接数
767    connection_created_count: Arc<AtomicU64>,
768    /// 累计关闭连接数
769    connection_closed_count: Arc<AtomicU64>,
770}
771
772/// Pool 克隆:仅增加 Arc 引用计数,成本极低
773///
774/// 克隆后的 Pool 与原 Pool 共享同一组连接池状态(idle 队列、计数器等)。
775impl Clone for Pool {
776    fn clone(&self) -> Self {
777        Self {
778            config: self.config.clone(),
779            factory: self.factory.clone(),
780            idle: self.idle.clone(),
781            total_count: self.total_count.clone(),
782            closed: self.closed.clone(),
783            notify: Arc::clone(&self.notify),
784            waiters_count: self.waiters_count.clone(),
785            dynamic_max_size: self.dynamic_max_size.clone(),
786            #[cfg(feature = "circuit-breaker")]
787            circuit_breaker: Arc::clone(&self.circuit_breaker),
788            #[cfg(feature = "rate-limit")]
789            rate_limiter: Arc::clone(&self.rate_limiter),
790            #[cfg(feature = "rate-limit")]
791            rate_limit_key: self.rate_limit_key.clone(),
792            acquire_count: self.acquire_count.clone(),
793            acquire_failed_count: self.acquire_failed_count.clone(),
794            acquire_wait_time_ns: self.acquire_wait_time_ns.clone(),
795            release_count: self.release_count.clone(),
796            connection_created_count: self.connection_created_count.clone(),
797            connection_closed_count: self.connection_closed_count.clone(),
798        }
799    }
800}
801
802impl Pool {
803    /// 创建连接池
804    ///
805    /// L-5 修复:补充示例文档
806    ///
807    /// # 示例
808    ///
809    /// ```ignore
810    /// use sz_orm_core::pool::{Pool, PoolConfig, PoolConfigBuilder, ConnectionFactory};
811    /// use std::sync::Arc;
812    ///
813    /// struct MyFactory;
814    /// impl ConnectionFactory for MyFactory {
815    ///     // ...
816    ///     # async fn create(&self) -> Result<Box<dyn Connection>, PoolError> { unimplemented!() }
817    /// }
818    ///
819    /// let config = PoolConfigBuilder::new()
820    ///     .max_size(10)
821    ///     .acquire_timeout(std::time::Duration::from_secs(30))
822    ///     .build();
823    /// let pool = Pool::new(config, Arc::new(MyFactory))?;
824    /// # Ok::<(), sz_orm_core::pool::PoolError>(())
825    /// ```
826    pub fn new(config: PoolConfig, factory: Arc<dyn ConnectionFactory>) -> Result<Self, PoolError> {
827        config.validate()?;
828        // v1.1.0 优化 2:容量固定为 max_size,total_count 已限制池中总连接数
829        // 先提取 max_size,避免 config 在结构体字面量中被 move 后再用
830        let max_size = config.max_size as usize;
831        let dynamic_max = config.max_size;
832        Ok(Self {
833            config,
834            factory,
835            idle: Arc::new(ArrayQueue::new(max_size)),
836            total_count: Arc::new(AtomicU32::new(0)),
837            closed: Arc::new(AtomicBool::new(false)),
838            notify: Arc::new(Notify::new()),
839            waiters_count: Arc::new(AtomicU32::new(0)),
840            dynamic_max_size: Arc::new(AtomicU32::new(dynamic_max)),
841            // #88 修复:默认断路器配置(5 次连续失败跳闸,30 秒后进入 HalfOpen)
842            // P1-4 修复:使用核心层 DefaultCircuitBreaker,而非 sz_orm_health::CircuitBreaker
843            #[cfg(feature = "circuit-breaker")]
844            circuit_breaker: Arc::new(PlMutex::new(DefaultCircuitBreaker::new(
845                5,
846                std::time::Duration::from_secs(30),
847            ))),
848            // #93 修复:默认无限流器(调用方通过 set_rate_limiter 配置)
849            // P1-4 修复:使用 parking_lot::RwLock,而非 std::sync::RwLock
850            #[cfg(feature = "rate-limit")]
851            rate_limiter: Arc::new(PlRwLock::new(None)),
852            #[cfg(feature = "rate-limit")]
853            rate_limit_key: "pool".to_string(),
854            acquire_count: Arc::new(AtomicU64::new(0)),
855            acquire_failed_count: Arc::new(AtomicU64::new(0)),
856            acquire_wait_time_ns: Arc::new(AtomicU64::new(0)),
857            release_count: Arc::new(AtomicU64::new(0)),
858            connection_created_count: Arc::new(AtomicU64::new(0)),
859            connection_closed_count: Arc::new(AtomicU64::new(0)),
860        })
861    }
862
863    /// 连接池预热(TASK-021)
864    ///
865    /// 当 `PoolConfig::prewarm` 为 `true` 时,调用此方法会立即建立 `min_idle` 个连接
866    /// 并放入空闲队列。预热失败不阻断池创建(仅记录 `tracing::warn!`)。
867    ///
868    /// **注意**:`Pool::new()` 是同步方法,无法内部执行异步预热。
869    /// 调用方需要在创建池后手动调用 `pool.prewarm().await`:
870    ///
871    /// ```ignore
872    /// let config = PoolConfig::default().with_prewarm(true).min_idle(5);
873    /// let pool = Pool::new(config, factory)?;
874    /// pool.prewarm().await; // 手动预热
875    /// // 此时池中已有 5 个连接
876    /// ```
877    ///
878    /// 预热后首次 `acquire()` 延迟 < 10ms(对比冷启动 < 100ms)。
879    pub async fn prewarm(&self) {
880        if !self.config.prewarm {
881            return;
882        }
883
884        let min_idle = self.config.min_idle as usize;
885        let mut warmed = 0;
886
887        for i in 0..min_idle {
888            // 检查池是否已关闭
889            if self.closed.load(Ordering::Acquire) {
890                break;
891            }
892
893            // 检查是否已达上限
894            let current_max = self.dynamic_max_size.load(Ordering::Acquire);
895            let current = self.total_count.load(Ordering::Acquire);
896            if current >= current_max {
897                break;
898            }
899
900            // 尝试递增 total_count
901            let created = loop {
902                let current = self.total_count.load(Ordering::Acquire);
903                if current >= current_max {
904                    break None;
905                }
906                match self.total_count.compare_exchange(
907                    current,
908                    current + 1,
909                    Ordering::SeqCst,
910                    Ordering::Acquire,
911                ) {
912                    Ok(_) => break Some(()),
913                    Err(_) => continue,
914                }
915            };
916
917            if created.is_some() {
918                match tokio::time::timeout(self.config.connection_timeout, self.factory.create())
919                    .await
920                {
921                    Ok(Ok(conn)) => {
922                        #[cfg(feature = "circuit-breaker")]
923                        {
924                            self.circuit_breaker.lock().record_success();
925                        }
926                        self.emit_event(PoolEvent::ConnectionCreated);
927                        let pooled = PooledConnection::new(conn, self.clone());
928                        // 放入空闲队列
929                        if self.idle.push(pooled).is_err() {
930                            // 队列满(不应该发生),关闭连接
931                            let _ = self.total_count.fetch_sub(1, Ordering::SeqCst);
932                            tracing::warn!(
933                                target: "sz_orm::pool::prewarm",
934                                "prewarm connection {} failed: idle queue full",
935                                i
936                            );
937                        } else {
938                            warmed += 1;
939                            self.notify.notify_one();
940                        }
941                    }
942                    Ok(Err(e)) => {
943                        let _ = self.total_count.fetch_sub(1, Ordering::SeqCst);
944                        #[cfg(feature = "circuit-breaker")]
945                        {
946                            self.circuit_breaker.lock().record_failure();
947                        }
948                        tracing::warn!(
949                            target: "sz_orm::pool::prewarm",
950                            "prewarm connection {} failed: {}",
951                            i,
952                            e
953                        );
954                    }
955                    Err(_) => {
956                        let _ = self.total_count.fetch_sub(1, Ordering::SeqCst);
957                        #[cfg(feature = "circuit-breaker")]
958                        {
959                            self.circuit_breaker.lock().record_failure();
960                        }
961                        tracing::warn!(
962                            target: "sz_orm::pool::prewarm",
963                            "prewarm connection {} timeout",
964                            i
965                        );
966                    }
967                }
968            }
969        }
970
971        if warmed > 0 {
972            tracing::info!(
973                target: "sz_orm::pool::prewarm",
974                "pool prewarm completed: {}/{} connections established",
975                warmed,
976                min_idle
977            );
978        }
979    }
980
981    /// 获取配置
982    pub fn config(&self) -> &PoolConfig {
983        &self.config
984    }
985
986    /// #88 修复:配置断路器(启用 `circuit-breaker` feature 时生效)
987    ///
988    /// 替换默认的断路器实例。调用此方法可自定义 `failure_threshold` 和 `reset_timeout`。
989    ///
990    /// # 示例
991    ///
992    /// ```ignore
993    /// # use sz_orm_core::pool::{Pool, PoolConfig};
994    /// # use std::time::Duration;
995    /// # fn example(pool: &Pool) {
996    /// pool.configure_circuit_breaker(10, Duration::from_secs(60));
997    /// # }
998    /// ```
999    #[cfg(feature = "circuit-breaker")]
1000    pub fn configure_circuit_breaker(
1001        &self,
1002        failure_threshold: usize,
1003        reset_timeout: std::time::Duration,
1004    ) {
1005        let new_cb = DefaultCircuitBreaker::new(failure_threshold, reset_timeout);
1006        // P1-4 修复:parking_lot::Mutex::lock 直接返回 guard,无 PoisonError
1007        let mut guard = self.circuit_breaker.lock();
1008        *guard = new_cb;
1009    }
1010
1011    /// #88 修复:手动重置断路器到 Closed 状态
1012    ///
1013    /// 用于故障排除后手动恢复,无视当前 reset_timeout 是否到达。
1014    /// 返回是否实际发生了状态变更。
1015    #[cfg(feature = "circuit-breaker")]
1016    pub fn reset_circuit_breaker(&self) -> bool {
1017        // P1-4 修复:parking_lot::Mutex::lock 直接返回 guard,无 PoisonError
1018        let mut guard = self.circuit_breaker.lock();
1019        guard.reset()
1020    }
1021
1022    /// #88 修复:获取断路器当前状态
1023    #[cfg(feature = "circuit-breaker")]
1024    pub fn circuit_state(&self) -> CircuitState {
1025        // P1-4 修复:parking_lot::Mutex::lock 直接返回 guard,无 PoisonError
1026        let guard = self.circuit_breaker.lock();
1027        guard.state()
1028    }
1029
1030    /// #93 修复:配置限流器(启用 `rate-limit` feature 时生效)
1031    ///
1032    /// 替换当前的限流器实例。传入 `None` 可禁用限流。
1033    /// 默认限流 key 为 `"pool"`,可通过 `with_rate_limit_key` 修改。
1034    ///
1035    /// P1-4 修复:参数类型使用核心层 `crate::rate_limiter::RateLimiter` trait,
1036    /// 而非 `sz_orm_limit::RateLimiter`,消除反向依赖。
1037    /// sz-orm-limit 包的所有限流器实现均已实现此 trait。
1038    #[cfg(feature = "rate-limit")]
1039    pub fn set_rate_limiter(&self, limiter: Option<Arc<dyn RateLimiter>>) {
1040        // P1-4 修复:parking_lot::RwLock::write 直接返回 guard,无 PoisonError
1041        let mut guard = self.rate_limiter.write();
1042        *guard = limiter;
1043    }
1044
1045    /// #93 修复:设置限流 key(按用户/IP 维度限流时使用)
1046    #[cfg(feature = "rate-limit")]
1047    pub fn with_rate_limit_key(mut self, key: impl Into<String>) -> Self {
1048        self.rate_limit_key = key.into();
1049        self
1050    }
1051
1052    /// 触发连接池事件回调
1053    fn emit_event(&self, event: PoolEvent) {
1054        // Prometheus 风格统计:连接创建事件统一在此计数
1055        // (所有创建路径均通过 emit_event(ConnectionCreated) 上报)
1056        if matches!(event, PoolEvent::ConnectionCreated) {
1057            self.connection_created_count
1058                .fetch_add(1, Ordering::Relaxed);
1059        }
1060        if let Some(ref callback) = self.config.on_event {
1061            callback(event);
1062        }
1063    }
1064
1065    /// 关闭连接并记录统计(统一入口)
1066    ///
1067    /// 所有连接关闭路径必须通过此方法,确保 `connection_closed_count`
1068    /// 与 `total_count` 递减的统计口径一致。
1069    async fn close_connection(&self, pooled: PooledConnection) {
1070        let mut pooled = pooled;
1071        let _ = pooled.conn.close().await;
1072        self.connection_closed_count.fetch_add(1, Ordering::Relaxed);
1073    }
1074
1075    /// 从池中获取连接(带超时)
1076    ///
1077    /// L-5 修复:补充示例文档
1078    ///
1079    /// 超时时间由 `PoolConfig::acquire_timeout` 控制,默认 30 秒。
1080    /// 若超时则返回 `PoolError::AcquireTimeout`。
1081    ///
1082    /// # 示例
1083    ///
1084    /// ```ignore
1085    /// # use sz_orm_core::pool::Pool;
1086    /// # async fn example(pool: &Pool) -> Result<(), Box<dyn std::error::Error>> {
1087    /// // 从池中获取连接
1088    /// let conn = pool.acquire().await?;
1089    /// // 使用连接执行查询...
1090    /// // conn.query("SELECT 1").await?;
1091    /// # Ok(())
1092    /// # }
1093    /// ```
1094    #[tracing::instrument(skip(self), fields(max_size = self.config.max_size, acquire_timeout = ?self.config.acquire_timeout))]
1095    pub async fn acquire(&self) -> Result<PooledConnection, PoolError> {
1096        // close_all 后拒绝新 acquire
1097        if self.closed.load(Ordering::Acquire) {
1098            self.acquire_failed_count.fetch_add(1, Ordering::Relaxed);
1099            return Err(PoolError::Closed);
1100        }
1101
1102        // #88 修复:断路器检查(启用 circuit-breaker feature 时生效)
1103        // 当数据库连续失败超过阈值时,断路器跳闸,拒绝新 acquire 请求
1104        // P1-4 修复:parking_lot::Mutex::lock 直接返回 guard,无 PoisonError
1105        #[cfg(feature = "circuit-breaker")]
1106        {
1107            let mut guard = self.circuit_breaker.lock();
1108            if !guard.can_execute() {
1109                self.acquire_failed_count.fetch_add(1, Ordering::Relaxed);
1110                return Err(PoolError::CircuitOpen);
1111            }
1112        }
1113
1114        // #93 修复:限流器检查(启用 rate-limit feature 时生效)
1115        // 在 acquire 前调用 try_acquire,被拒绝时返回 RateLimited
1116        // P1-4 修复:parking_lot::RwLock::read 直接返回 guard,无 PoisonError
1117        #[cfg(feature = "rate-limit")]
1118        {
1119            let guard = self.rate_limiter.read();
1120            if let Some(ref limiter) = *guard {
1121                match limiter.try_acquire(&self.rate_limit_key) {
1122                    Ok(result) if !result.allowed => {
1123                        self.acquire_failed_count.fetch_add(1, Ordering::Relaxed);
1124                        return Err(PoolError::RateLimited {
1125                            remaining: result.remaining,
1126                            reset_at: result.reset_at,
1127                        });
1128                    }
1129                    Ok(_) => {} // 放行
1130                    Err(_) => {
1131                        // 限流器内部错误,保守放行(避免误杀)
1132                    }
1133                }
1134            }
1135        }
1136
1137        let deadline = Instant::now() + self.config.acquire_timeout;
1138        // 指数退避初始值(等待连接归还时的重试间隔)
1139        let mut backoff = Duration::from_millis(1);
1140        // 指数退避上限(避免等待者频繁唤醒消耗 CPU)
1141        const MAX_BACKOFF: Duration = Duration::from_millis(100);
1142
1143        loop {
1144            // v1.1.0 优化 2:从空闲连接中获取(无锁 pop)
1145            //
1146            // `ArrayQueue::pop()` 是单次 CAS 原子操作,无需 await Mutex 锁。
1147            // 仍保留 to_close Vec:检查过期/空闲过久/is_connected 失败的连接
1148            // 先收集到本地 Vec,循环结束后再批量 close(不在循环内 await)。
1149            let mut to_close: Vec<PooledConnection> = Vec::new();
1150            let acquired: Option<PooledConnection> = {
1151                let mut found: Option<PooledConnection> = None;
1152                while let Some(pooled) = self.idle.pop() {
1153                    // 检查连接是否过期
1154                    if pooled.is_expired(self.config.max_lifetime) {
1155                        to_close.push(pooled);
1156                        continue;
1157                    }
1158                    // 检查连接是否空闲过久
1159                    if pooled.is_idle_too_long(self.config.idle_timeout) {
1160                        to_close.push(pooled);
1161                        continue;
1162                    }
1163                    // 检查连接是否仍然连接
1164                    // 注意:is_connected() 是同步内存检查,不涉及 I/O
1165                    if !pooled.conn.is_connected() {
1166                        to_close.push(pooled);
1167                        continue;
1168                    }
1169                    found = Some(pooled);
1170                    break;
1171                }
1172                found
1173            };
1174
1175            // 批量 close 过期连接(不持任何锁)
1176            for pooled in to_close {
1177                self.close_connection(pooled).await;
1178                // v0.2.1 修复 P-1:AtomicU32 替代 Mutex<u32>
1179                self.total_count.fetch_sub(1, Ordering::SeqCst);
1180            }
1181
1182            if let Some(mut pooled) = acquired {
1183                // P1-1:test_before_acquire — 从空闲队列取出的连接先 ping 验证存活
1184                if self.config.test_before_acquire {
1185                    let ping_timeout = self.config.connection_timeout / 2;
1186                    let alive = match tokio::time::timeout(ping_timeout, pooled.conn.ping()).await {
1187                        Ok(true) => true,
1188                        Ok(false) => false,
1189                        Err(_) => false, // ping 超时,连接可能卡住
1190                    };
1191                    if !alive {
1192                        // ping 失败:关闭连接,回退计数,继续循环重新 acquire
1193                        self.close_connection(pooled).await;
1194                        self.total_count.fetch_sub(1, Ordering::SeqCst);
1195                        continue;
1196                    }
1197                }
1198                // 从 idle 获取的连接 pool 字段为 None(release 时清除),
1199                // 重新设置 pool 引用以支持 Drop 自动归还
1200                pooled.pool = Some(self.clone());
1201                self.acquire_count.fetch_add(1, Ordering::Relaxed);
1202                return Ok(pooled);
1203            }
1204
1205            // 尝试创建新连接
1206            // v0.2.1 修复 P-1:用 AtomicU32::compare_exchange 替代 Mutex<u32>
1207            // CAS 循环:先尝试递增 total_count,如果成功则创建连接
1208            // 使用 dynamic_max_size 以支持 resize 动态调整
1209            let current_max = self.dynamic_max_size.load(Ordering::Acquire);
1210            let created = loop {
1211                let current = self.total_count.load(Ordering::Acquire);
1212                if current >= current_max {
1213                    break None; // 已达上限,不能创建
1214                }
1215                match self.total_count.compare_exchange(
1216                    current,
1217                    current + 1,
1218                    Ordering::SeqCst,
1219                    Ordering::Acquire,
1220                ) {
1221                    Ok(_) => break Some(()), // CAS 成功,可以创建
1222                    Err(_) => continue,      // 被其他线程抢先,重试
1223                }
1224            };
1225
1226            if created.is_some() {
1227                match tokio::time::timeout(self.config.connection_timeout, self.factory.create())
1228                    .await
1229                {
1230                    Ok(Ok(conn)) => {
1231                        // #88 修复:连接创建成功,记录到断路器
1232                        // P1-4 修复:parking_lot::Mutex::lock 直接返回 guard,无 PoisonError
1233                        #[cfg(feature = "circuit-breaker")]
1234                        {
1235                            self.circuit_breaker.lock().record_success();
1236                        }
1237                        self.emit_event(PoolEvent::ConnectionCreated);
1238                        self.emit_event(PoolEvent::ConnectionAcquired);
1239                        self.acquire_count.fetch_add(1, Ordering::Relaxed);
1240                        return Ok(PooledConnection::new(conn, self.clone()));
1241                    }
1242                    Ok(Err(e)) => {
1243                        // 创建失败,回退计数
1244                        self.total_count.fetch_sub(1, Ordering::SeqCst);
1245                        // #88 修复:连接创建失败,记录到断路器
1246                        // P1-4 修复:parking_lot::Mutex::lock 直接返回 guard,无 PoisonError
1247                        #[cfg(feature = "circuit-breaker")]
1248                        {
1249                            self.circuit_breaker.lock().record_failure();
1250                        }
1251                        self.acquire_failed_count.fetch_add(1, Ordering::Relaxed);
1252                        return Err(PoolError::ConnectionFailed(e.to_string()));
1253                    }
1254                    Err(_) => {
1255                        // tokio::time::timeout 的 Err 必为超时
1256                        self.total_count.fetch_sub(1, Ordering::SeqCst);
1257                        // #88 修复:连接创建超时,记录到断路器
1258                        // P1-4 修复:parking_lot::Mutex::lock 直接返回 guard,无 PoisonError
1259                        #[cfg(feature = "circuit-breaker")]
1260                        {
1261                            self.circuit_breaker.lock().record_failure();
1262                        }
1263                        self.acquire_failed_count.fetch_add(1, Ordering::Relaxed);
1264                        return Err(PoolError::Timeout);
1265                    }
1266                }
1267            }
1268
1269            // 等待连接释放或超时(带指数退避)
1270            let now = Instant::now();
1271            if now >= deadline {
1272                self.emit_event(PoolEvent::AcquireTimeout);
1273                self.acquire_failed_count.fetch_add(1, Ordering::Relaxed);
1274                return Err(PoolError::Timeout);
1275            }
1276            // 增加等待者计数
1277            self.waiters_count.fetch_add(1, Ordering::SeqCst);
1278            let wait = std::cmp::min(backoff, deadline - now);
1279            match tokio::time::timeout(wait, self.notify.notified()).await {
1280                Ok(()) => {
1281                    // 收到通知,重置退避
1282                    backoff = Duration::from_millis(1);
1283                }
1284                Err(_) => {
1285                    // 本次等待超时,增加退避(指数增长,上限 MAX_BACKOFF)
1286                    backoff = std::cmp::min(backoff * 2, MAX_BACKOFF);
1287                }
1288            }
1289            // 减少等待者计数
1290            self.waiters_count.fetch_sub(1, Ordering::SeqCst);
1291            // Prometheus 风格统计:累计本次实际等待时长(纳秒)
1292            self.acquire_wait_time_ns
1293                .fetch_add(wait.as_nanos() as u64, Ordering::Relaxed);
1294        }
1295    }
1296
1297    /// 释放连接回池中
1298    /// 如果池已关闭或连接已断开,则直接关闭连接而不是放回池中。
1299    ///
1300    /// 接收 `PooledConnection` 以保留原始 `created_at`,避免 `max_lifetime`
1301    /// 在每次归还后被重置(Critical bug fix)。
1302    ///
1303    /// 显式调用 release 后,`pooled.pool` 设为 None,避免 Drop 重复归还。
1304    #[tracing::instrument(skip(self, pooled))]
1305    pub async fn release(&self, mut pooled: PooledConnection) {
1306        // 标记已显式归还,避免 Drop 重复归还
1307        pooled.pool = None;
1308        // Prometheus 风格统计:每次 release 调用计一次(含直接关闭路径)
1309        self.release_count.fetch_add(1, Ordering::Relaxed);
1310
1311        // 检查池是否已关闭
1312        if self.closed.load(Ordering::Acquire) {
1313            self.close_connection(pooled).await;
1314            // v0.2.1 修复 P-1:AtomicU32
1315            self.total_count.fetch_sub(1, Ordering::SeqCst);
1316            self.emit_event(PoolEvent::ConnectionClosed);
1317            return;
1318        }
1319
1320        // 检查连接是否仍然有效
1321        if !pooled.conn.is_connected() {
1322            self.close_connection(pooled).await;
1323            self.total_count.fetch_sub(1, Ordering::SeqCst);
1324            self.emit_event(PoolEvent::ConnectionClosed);
1325            return;
1326        }
1327
1328        // 更新 last_used_at(归还时间),但保留 created_at(原始创建时间)
1329        pooled.last_used_at = Instant::now();
1330
1331        // v1.1.0 优化 2:无锁 push 替换 Mutex<VecDeque>::push_back
1332        //
1333        // `ArrayQueue::push` 返回 `Result<(), T>`,失败表示队列满。
1334        // 正常情况下不会满(因为 `total_count` 限制了池中总连接数 ≤ max_size = 队列容量),
1335        // 但仍处理失败情况:取出所有权并关闭连接,避免连接泄漏。
1336        if let Err(rejected) = self.idle.push(pooled) {
1337            // 队列满(极端并发场景),关闭被拒绝的连接
1338            self.close_connection(rejected).await;
1339            self.total_count.fetch_sub(1, Ordering::SeqCst);
1340            self.emit_event(PoolEvent::ConnectionClosed);
1341        } else {
1342            self.emit_event(PoolEvent::ConnectionReleased);
1343        }
1344        self.notify.notify_one();
1345    }
1346
1347    /// 获取池状态
1348    ///
1349    /// v1.1.0 优化 2:`idle` 长度从 `Mutex::lock().await` 改为 `ArrayQueue::len()`
1350    /// (原子 load,无任何等待)。该方法保留 `async` 签名以兼容旧调用方。
1351    pub async fn status(&self) -> PoolStatus {
1352        let idle_count = self.idle.len() as u32;
1353        // v0.2.1 修复 P-1:AtomicU32
1354        let active = self.total_count.load(Ordering::Acquire);
1355        let waiters = self.waiters_count.load(Ordering::Acquire);
1356        PoolStatus {
1357            idle: idle_count,
1358            active,
1359            max: self.dynamic_max_size.load(Ordering::Acquire),
1360            min: self.config.min_idle,
1361            waiters,
1362        }
1363    }
1364
1365    /// 获取连接池累计统计指标(Prometheus 风格)
1366    ///
1367    /// 返回池生命周期内的累计计数,可通过监控系统(如 Prometheus 抓取)
1368    /// 观察连接池的健康状况与压力:
1369    ///
1370    /// - `acquire_count` / `acquire_failed_count`:获取成功率
1371    /// - `acquire_wait_time`:池满时等待的累计时长(配合 `average_acquire_wait_time()` 评估延迟)
1372    /// - `connection_created_count` / `connection_closed_count`:连接波动
1373    ///
1374    /// 计数基于无锁原子操作,调用开销可忽略。
1375    pub fn pool_metrics(&self) -> PoolMetrics {
1376        PoolMetrics {
1377            acquire_count: self.acquire_count.load(Ordering::Acquire),
1378            acquire_failed_count: self.acquire_failed_count.load(Ordering::Acquire),
1379            acquire_wait_time: Duration::from_nanos(
1380                self.acquire_wait_time_ns.load(Ordering::Acquire),
1381            ),
1382            release_count: self.release_count.load(Ordering::Acquire),
1383            connection_created_count: self.connection_created_count.load(Ordering::Acquire),
1384            connection_closed_count: self.connection_closed_count.load(Ordering::Acquire),
1385        }
1386    }
1387
1388    /// 回收空闲过久的连接
1389    #[tracing::instrument(skip(self))]
1390    pub async fn reap_idle(&self) {
1391        // v1.1.0 优化 2:使用 `ArrayQueue::pop` 循环取出所有连接,过滤后再 push 回去。
1392        // 无锁操作,无需 `Mutex::lock().await`。
1393        // 1. 取出所有空闲连接到本地 Vec
1394        let mut all: Vec<PooledConnection> = Vec::new();
1395        while let Some(pooled) = self.idle.pop() {
1396            all.push(pooled);
1397        }
1398
1399        // 2. 分类:保留 vs 关闭
1400        let mut to_close = Vec::new();
1401        for pooled in all {
1402            if pooled.is_idle_too_long(self.config.idle_timeout)
1403                || pooled.is_expired(self.config.max_lifetime)
1404            {
1405                to_close.push(pooled);
1406            } else {
1407                // push 回队列(容量足够,因为之前刚从这里 pop 出来)
1408                if let Err(rejected) = self.idle.push(pooled) {
1409                    self.close_connection(rejected).await;
1410                    self.total_count.fetch_sub(1, Ordering::SeqCst);
1411                }
1412            }
1413        }
1414
1415        // 3. 关闭过期连接
1416        for pooled in to_close {
1417            self.close_connection(pooled).await;
1418            // v0.2.1 修复 P-1:AtomicU32 替代 Mutex<u32>
1419            self.total_count.fetch_sub(1, Ordering::SeqCst);
1420        }
1421    }
1422
1423    /// 关闭所有空闲连接,并标记池为已关闭
1424    /// 注意:已借出未归还的连接不受影响,但归还时会被直接关闭;
1425    /// 同时 close_all 后的新 acquire 也会被拒绝。
1426    pub async fn close_all(&self) {
1427        // 标记为已关闭,阻止新 acquire/release
1428        self.closed.store(true, Ordering::Release);
1429        // v1.1.0 优化 2:使用 `ArrayQueue::pop` 循环取出所有空闲连接(无锁)。
1430        // 先收集到本地 Vec,再批量 close(不在循环内 await)。
1431        let mut to_close: Vec<PooledConnection> = Vec::new();
1432        while let Some(pooled) = self.idle.pop() {
1433            to_close.push(pooled);
1434        }
1435        // 批量 close(不持任何锁)
1436        let closed_count: u32 = to_close.len() as u32;
1437        for pooled in to_close {
1438            self.close_connection(pooled).await;
1439        }
1440        // 减少总连接计数(只减去已关闭的空闲连接数)
1441        // v0.2.1 修复 P-1:AtomicU32 替代 Mutex<u32>
1442        self.total_count.fetch_sub(closed_count, Ordering::SeqCst);
1443    }
1444
1445    /// M-7 修复:连接池健康检查(heartbeat)
1446    ///
1447    /// 对所有空闲连接执行 `ping()`,移除已断开或 ping 失败的连接。
1448    /// 调用方应定期调用此方法(如每 60 秒),以清理失效连接。
1449    ///
1450    /// # 返回值
1451    ///
1452    /// 返回被移除的连接数。
1453    ///
1454    /// # 注意
1455    ///
1456    /// - v1.1.0 优化 2 后:使用无锁 `ArrayQueue`,不再持 `Mutex` 锁。
1457    ///   仍可能在 ping 期间阻塞 acquire(因为连接已被取出),但不再阻塞 release。
1458    /// - 仅检查空闲连接,不影响已借出的连接
1459    /// - 对于大量空闲连接,可能产生较多并发 ping,建议在低峰期执行
1460    pub async fn health_check(&self) -> u32 {
1461        // v1.1.0 优化 2:使用 `ArrayQueue::pop` 收集所有空闲连接(无锁)
1462        let mut to_check: Vec<PooledConnection> = Vec::new();
1463        while let Some(pooled) = self.idle.pop() {
1464            to_check.push(pooled);
1465        }
1466
1467        let mut removed: u32 = 0;
1468        let mut alive: Vec<PooledConnection> = Vec::with_capacity(to_check.len());
1469        for mut pooled in to_check.drain(..) {
1470            // 先检查 is_connected(同步内存检查),再 ping(异步网络检查)
1471            if !pooled.conn.is_connected() {
1472                self.close_connection(pooled).await;
1473                removed += 1;
1474                continue;
1475            }
1476            // ping 超时设置为 connection_timeout 的一半,避免长时间阻塞
1477            let ping_timeout = self.config.connection_timeout / 2;
1478            match tokio::time::timeout(ping_timeout, pooled.conn.ping()).await {
1479                Ok(true) => alive.push(pooled),
1480                Ok(false) => {
1481                    // ping 返回 false,连接失效
1482                    self.close_connection(pooled).await;
1483                    removed += 1;
1484                }
1485                Err(_) => {
1486                    // ping 超时,连接可能卡住
1487                    self.close_connection(pooled).await;
1488                    removed += 1;
1489                }
1490            }
1491        }
1492
1493        // 将存活连接放回池中(无锁 push)
1494        let alive_count: u32 = alive.len() as u32;
1495        for pooled in alive {
1496            // push 回队列(容量足够,因为之前刚从这里 pop 出来)
1497            if let Err(rejected) = self.idle.push(pooled) {
1498                self.close_connection(rejected).await;
1499                removed += 1;
1500            }
1501        }
1502
1503        // 更新总连接计数
1504        if removed > 0 {
1505            self.total_count.fetch_sub(removed, Ordering::SeqCst);
1506        }
1507
1508        // 通知等待的 acquire 有连接可用
1509        if alive_count > 0 {
1510            self.notify.notify_one();
1511        }
1512
1513        removed
1514    }
1515
1516    /// 优雅停机:关闭所有空闲连接,等待所有在途连接归还
1517    ///
1518    /// 1. 标记池为已关闭(拒绝新 acquire)
1519    /// 2. 通知所有等待者(让 acquire 等待者立即返回 Closed 错误)
1520    /// 3. 关闭所有空闲连接(立即释放,避免 wait 阶段无意义等待)
1521    /// 4. 等待在途(已借出)连接归还(带 30 秒超时)
1522    pub async fn shutdown(&self) {
1523        // 1. 标记为关闭状态
1524        self.closed.store(true, Ordering::SeqCst);
1525        // 2. 通知所有等待者
1526        self.notify.notify_waiters();
1527        // 3. 关闭所有空闲连接(close_all 内部也会设置 closed,幂等)
1528        self.close_all().await;
1529        // 4. 等待在途连接归还(带超时)
1530        let deadline = Instant::now() + Duration::from_secs(30);
1531        while self.total_count.load(Ordering::SeqCst) > 0 {
1532            if Instant::now() >= deadline {
1533                break;
1534            }
1535            tokio::time::sleep(Duration::from_millis(100)).await;
1536        }
1537    }
1538
1539    /// 动态调整连接池最大容量(resize 的别名,接受 usize)
1540    ///
1541    /// 简化实现:仅更新动态 max_size 值,在 acquire 时检查新值。
1542    /// - 如果 new_max 大于当前值,允许创建更多连接(受 ArrayQueue 容量限制:
1543    ///   超出原始 max_size 的空闲连接会在 release 时因队列满而被关闭)
1544    /// - 如果 new_max 小于当前值,不立即关闭多余连接,但阻止新连接创建
1545    ///   (多余连接会在 release/reap_idle 时自然回收)
1546    pub fn resize(&self, new_max: usize) {
1547        self.set_max_size(new_max as u32);
1548    }
1549
1550    /// 动态调整连接池最大容量
1551    pub fn set_max_size(&self, new_max: u32) {
1552        self.dynamic_max_size.store(new_max, Ordering::SeqCst);
1553    }
1554
1555    /// 获取当前动态 max_size
1556    pub fn max_size(&self) -> u32 {
1557        self.dynamic_max_size.load(Ordering::Acquire)
1558    }
1559
1560    /// 预热连接池:创建指定数量的连接放入空闲队列
1561    ///
1562    /// 不会超过 `dynamic_max_size` 上限。创建失败时停止预热并返回 Ok。
1563    pub async fn warmup(&self, min_idle: usize) -> Result<(), PoolError> {
1564        for _ in 0..min_idle {
1565            let current_max = self.dynamic_max_size.load(Ordering::Acquire);
1566            let current = self.total_count.load(Ordering::Acquire);
1567            if current >= current_max {
1568                break;
1569            }
1570            // CAS 递增计数器,避免并发 warmup/acquire 超过 max_size
1571            match self.total_count.compare_exchange(
1572                current,
1573                current + 1,
1574                Ordering::SeqCst,
1575                Ordering::Acquire,
1576            ) {
1577                Ok(_) => {}
1578                Err(_) => continue, // 并发竞争,跳过本次
1579            }
1580            match self.factory.create().await {
1581                Ok(conn) => {
1582                    let now = Instant::now();
1583                    let pooled = PooledConnection {
1584                        conn,
1585                        created_at: now,
1586                        last_used_at: now,
1587                        pool: None,
1588                    };
1589                    if let Err(rejected) = self.idle.push(pooled) {
1590                        // 队列满(不应发生,因为 total_count 限制了),关闭并递减
1591                        self.close_connection(rejected).await;
1592                        self.total_count.fetch_sub(1, Ordering::SeqCst);
1593                    }
1594                    self.emit_event(PoolEvent::ConnectionCreated);
1595                }
1596                Err(_) => {
1597                    // 创建失败,回退计数器并停止预热
1598                    self.total_count.fetch_sub(1, Ordering::SeqCst);
1599                    break;
1600                }
1601            }
1602        }
1603        Ok(())
1604    }
1605
1606    /// 带超时的查询执行
1607    ///
1608    /// 强制 `query_timeout` 配置生效:使用 `tokio::time::timeout` 包裹
1609    /// `conn.query(sql)`,超时返回 `DbError::QueryError`。未配置时使用 30 秒默认值。
1610    pub async fn query_with_timeout(&self, sql: &str) -> Result<QueryRows, crate::DbError> {
1611        let timeout = self.config.query_timeout.unwrap_or(Duration::from_secs(30));
1612        let mut conn = self.acquire().await.map_err(crate::DbError::PoolError)?;
1613        tokio::time::timeout(timeout, conn.query(sql))
1614            .await
1615            .map_err(|_| crate::DbError::QueryError(format!("Query timeout after {:?}", timeout)))?
1616    }
1617}
1618
1619#[cfg(test)]
1620mod tests {
1621    use super::*;
1622
1623    /// 测试用的模拟连接
1624    struct MockConnection {
1625        connected: bool,
1626    }
1627
1628    impl MockConnection {
1629        fn new() -> Self {
1630            Self { connected: true }
1631        }
1632    }
1633
1634    impl Connection for MockConnection {
1635        fn execute<'a>(
1636            &'a mut self,
1637            _sql: &'a str,
1638        ) -> Pin<Box<dyn Future<Output = Result<u64, crate::DbError>> + Send + 'a>> {
1639            Box::pin(async move { Ok(1) })
1640        }
1641
1642        fn query<'a>(
1643            &'a mut self,
1644            _sql: &'a str,
1645        ) -> Pin<
1646            Box<
1647                dyn Future<
1648                        Output = Result<
1649                            Vec<std::collections::HashMap<String, crate::value::Value>>,
1650                            crate::DbError,
1651                        >,
1652                    > + Send
1653                    + 'a,
1654            >,
1655        > {
1656            Box::pin(async move { Ok(vec![]) })
1657        }
1658
1659        fn begin_transaction<'a>(
1660            &'a mut self,
1661        ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
1662            Box::pin(async move { Ok(()) })
1663        }
1664
1665        fn commit<'a>(
1666            &'a mut self,
1667        ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
1668            Box::pin(async move { Ok(()) })
1669        }
1670
1671        fn rollback<'a>(
1672            &'a mut self,
1673        ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
1674            Box::pin(async move { Ok(()) })
1675        }
1676
1677        fn is_connected(&self) -> bool {
1678            self.connected
1679        }
1680
1681        fn ping<'a>(&'a mut self) -> Pin<Box<dyn Future<Output = bool> + Send + 'a>> {
1682            Box::pin(async move { true })
1683        }
1684
1685        fn close<'a>(
1686            &'a mut self,
1687        ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
1688            Box::pin(async move {
1689                self.connected = false;
1690                Ok(())
1691            })
1692        }
1693    }
1694
1695    struct MockConnectionFactory;
1696
1697    #[async_trait]
1698    impl ConnectionFactory for MockConnectionFactory {
1699        async fn create(&self) -> Result<Box<dyn Connection>, crate::DbError> {
1700            Ok(Box::new(MockConnection::new()))
1701        }
1702    }
1703
1704    #[tokio::test]
1705    async fn test_pool_config_builder() -> Result<(), Box<dyn std::error::Error>> {
1706        let config = PoolConfigBuilder::new().max_size(50).min_idle(10).build()?;
1707
1708        assert_eq!(config.max_size, 50);
1709        assert_eq!(config.min_idle, 10);
1710        Ok(())
1711    }
1712
1713    #[test]
1714    fn test_pool_status_display() {
1715        let status = PoolStatus {
1716            idle: 5,
1717            active: 10,
1718            max: 100,
1719            min: 5,
1720            waiters: 0,
1721        };
1722
1723        let display = format!("{:?}", status);
1724        assert!(display.contains("idle"));
1725        assert!(display.contains("active"));
1726    }
1727
1728    #[test]
1729    fn test_default_pool_config() {
1730        let config = PoolConfig::default();
1731        assert_eq!(config.max_size, 100);
1732        assert_eq!(config.min_idle, 0);
1733        assert_eq!(config.acquire_timeout.as_secs(), 30);
1734        assert_eq!(config.idle_timeout.as_secs(), 600);
1735        assert_eq!(config.max_lifetime.as_secs(), 1800);
1736    }
1737
1738    #[tokio::test]
1739    async fn test_pool_config_clone() {
1740        let config = PoolConfig::default();
1741        let cloned = config.clone();
1742        assert_eq!(cloned.max_size, config.max_size);
1743        assert_eq!(cloned.min_idle, config.min_idle);
1744    }
1745
1746    #[test]
1747    fn test_pool_config_builder_default() -> Result<(), Box<dyn std::error::Error>> {
1748        let builder = PoolConfigBuilder::new();
1749        let config = builder.build()?;
1750        assert_eq!(config.max_size, 100);
1751        Ok(())
1752    }
1753
1754    #[test]
1755    fn test_pool_config_validate() {
1756        let result = PoolConfigBuilder::new().max_size(0).build();
1757        assert!(result.is_err());
1758
1759        let result = PoolConfigBuilder::new().max_size(10).min_idle(20).build();
1760        assert!(result.is_err());
1761    }
1762
1763    #[test]
1764    fn test_pool_config_validate_duration_upper_bound() {
1765        use std::time::Duration;
1766
1767        // u64::MAX 秒应被拒绝(远超 u32::MAX 上限)
1768        let config = PoolConfig {
1769            max_size: 10,
1770            min_idle: 1,
1771            acquire_timeout: Duration::from_secs(u64::MAX),
1772            idle_timeout: Duration::from_secs(1),
1773            max_lifetime: Duration::from_secs(1),
1774            connection_timeout: Duration::from_secs(5),
1775            tls: None,
1776            query_timeout: None,
1777            max_rows: None,
1778            memory_limit: None,
1779            on_event: None,
1780            test_before_acquire: false,
1781            prewarm: false,
1782        };
1783        assert!(config.validate().is_err());
1784
1785        // u32::MAX 秒(≈136 年)恰好在上限内,应通过
1786        let config = PoolConfig {
1787            max_size: 10,
1788            min_idle: 1,
1789            acquire_timeout: Duration::from_secs(u32::MAX as u64),
1790            idle_timeout: Duration::from_secs(1),
1791            max_lifetime: Duration::from_secs(1),
1792            connection_timeout: Duration::from_secs(5),
1793            tls: None,
1794            query_timeout: None,
1795            max_rows: None,
1796            memory_limit: None,
1797            on_event: None,
1798            test_before_acquire: false,
1799            prewarm: false,
1800        };
1801        assert!(config.validate().is_ok());
1802
1803        // u32::MAX + 1 秒应被拒绝
1804        let config = PoolConfig {
1805            max_size: 10,
1806            min_idle: 1,
1807            acquire_timeout: Duration::from_secs(u32::MAX as u64 + 1),
1808            idle_timeout: Duration::from_secs(1),
1809            max_lifetime: Duration::from_secs(1),
1810            connection_timeout: Duration::from_secs(5),
1811            tls: None,
1812            query_timeout: None,
1813            max_rows: None,
1814            memory_limit: None,
1815            on_event: None,
1816            test_before_acquire: false,
1817            prewarm: false,
1818        };
1819        assert!(config.validate().is_err());
1820    }
1821
1822    #[test]
1823    fn test_pool_config_test_before_acquire_default() {
1824        // P1-1:test_before_acquire 默认关闭
1825        let config = PoolConfig::default();
1826        assert!(!config.test_before_acquire);
1827    }
1828
1829    #[test]
1830    fn test_pool_config_builder_test_before_acquire() {
1831        // P1-1:builder 设置 test_before_acquire
1832        let config = PoolConfigBuilder::new()
1833            .test_before_acquire(true)
1834            .build()
1835            .unwrap();
1836        assert!(config.test_before_acquire);
1837    }
1838
1839    #[tokio::test]
1840    async fn test_pool_acquire_and_release() -> Result<(), Box<dyn std::error::Error>> {
1841        let config = PoolConfigBuilder::new().max_size(5).min_idle(1).build()?;
1842        let factory = Arc::new(MockConnectionFactory);
1843        let pool = Pool::new(config, factory)?;
1844
1845        let conn = pool.acquire().await?;
1846        let status = pool.status().await;
1847        assert_eq!(status.active, 1);
1848        assert_eq!(status.idle, 0);
1849
1850        pool.release(conn).await;
1851        let status = pool.status().await;
1852        assert_eq!(status.idle, 1);
1853
1854        // 再次获取应该复用空闲连接
1855        let _conn2 = pool.acquire().await?;
1856        let status = pool.status().await;
1857        assert_eq!(status.idle, 0);
1858        Ok(())
1859    }
1860
1861    #[tokio::test]
1862    async fn test_pool_status() -> Result<(), Box<dyn std::error::Error>> {
1863        let config = PoolConfigBuilder::new().max_size(10).min_idle(2).build()?;
1864        let factory = Arc::new(MockConnectionFactory);
1865        let pool = Pool::new(config, factory)?;
1866
1867        let status = pool.status().await;
1868        assert_eq!(status.max, 10);
1869        assert_eq!(status.min, 2);
1870        assert_eq!(status.active, 0);
1871        Ok(())
1872    }
1873
1874    #[tokio::test]
1875    async fn test_pool_close_all() -> Result<(), Box<dyn std::error::Error>> {
1876        let config = PoolConfigBuilder::new().max_size(5).build()?;
1877        let factory = Arc::new(MockConnectionFactory);
1878        let pool = Pool::new(config, factory)?;
1879
1880        // 创建几个连接然后释放
1881        let conn1 = pool.acquire().await?;
1882        let conn2 = pool.acquire().await?;
1883        pool.release(conn1).await;
1884        pool.release(conn2).await;
1885
1886        pool.close_all().await;
1887        let status = pool.status().await;
1888        assert_eq!(status.idle, 0);
1889        assert_eq!(status.active, 0);
1890        Ok(())
1891    }
1892
1893    #[tokio::test]
1894    async fn test_pool_reap_idle() -> Result<(), Box<dyn std::error::Error>> {
1895        let config = PoolConfigBuilder::new()
1896            .max_size(5)
1897            .idle_timeout(0) // 立即超时
1898            .build()?;
1899        let factory = Arc::new(MockConnectionFactory);
1900        let pool = Pool::new(config, factory)?;
1901
1902        let conn = pool.acquire().await?;
1903        pool.release(conn).await;
1904
1905        // 等待一下确保空闲超时
1906        tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
1907
1908        pool.reap_idle().await;
1909        let status = pool.status().await;
1910        assert_eq!(status.idle, 0);
1911        Ok(())
1912    }
1913
1914    /// H-7 验证:acquire_timeout 默认 30s
1915    ///
1916    /// PoolConfig::default().acquire_timeout == 30s
1917    /// Pool::acquire() 内部使用 `deadline = Instant::now() + acquire_timeout`
1918    /// 超时后返回 `PoolError::Timeout`。
1919    #[tokio::test]
1920    async fn test_h7_acquire_timeout_default_30s() {
1921        let config = PoolConfig::default();
1922        assert_eq!(
1923            config.acquire_timeout,
1924            Duration::from_secs(30),
1925            "H-7: acquire_timeout 默认应为 30s"
1926        );
1927    }
1928
1929    /// H-7 验证:acquire_timeout 可通过 builder 配置
1930    #[tokio::test]
1931    async fn test_h7_acquire_timeout_configurable() -> Result<(), Box<dyn std::error::Error>> {
1932        let config = PoolConfigBuilder::new()
1933            .max_size(1)
1934            .acquire_timeout(5) // 5s
1935            .build()?;
1936        assert_eq!(config.acquire_timeout, Duration::from_secs(5));
1937
1938        // 创建 max_size=1 的池,acquire 一个连接(占满),第二次 acquire 应超时
1939        let factory = Arc::new(MockConnectionFactory);
1940        let pool = Pool::new(config, factory)?;
1941        let _conn1 = pool.acquire().await?;
1942
1943        // 第二次 acquire 应在 5s 后超时(这里用 1ms 超时配置加速测试)
1944        let fast_config = PoolConfigBuilder::new()
1945            .max_size(1)
1946            .acquire_timeout(0) // 立即超时(0s 超时;deadline 为 now)
1947            .build()?;
1948        // 注意:acquire_timeout(0) 是合法值,表示 deadline 为 now
1949        // 实际行为:第一次循环即检查 deadline,返回 Timeout
1950        let fast_pool = Pool::new(fast_config, Arc::new(MockConnectionFactory))?;
1951        let _fast_conn = fast_pool.acquire().await?; // 占满 max_size=1
1952        let result = fast_pool.acquire().await;
1953        assert!(
1954            matches!(result, Err(PoolError::Timeout)),
1955            "H-7: 应返回 Timeout"
1956        );
1957        Ok(())
1958    }
1959
1960    // ==================== M-7 健康检查测试 ====================
1961
1962    #[tokio::test]
1963    async fn test_m7_health_check_removes_nothing_when_all_healthy(
1964    ) -> Result<(), Box<dyn std::error::Error>> {
1965        // 所有连接健康时,health_check 应返回 0
1966        let config = PoolConfigBuilder::new().max_size(5).build()?;
1967        let factory = Arc::new(MockConnectionFactory);
1968        let pool = Pool::new(config, factory)?;
1969
1970        // 创建 3 个连接并归还到池中
1971        let conn1 = pool.acquire().await?;
1972        let conn2 = pool.acquire().await?;
1973        let conn3 = pool.acquire().await?;
1974        pool.release(conn1).await;
1975        pool.release(conn2).await;
1976        pool.release(conn3).await;
1977
1978        let removed = pool.health_check().await;
1979        assert_eq!(removed, 0, "Healthy connections should not be removed");
1980
1981        let status = pool.status().await;
1982        assert_eq!(status.idle, 3);
1983        assert_eq!(status.active, 3);
1984        Ok(())
1985    }
1986
1987    #[tokio::test]
1988    async fn test_m7_health_check_returns_zero_for_empty_pool(
1989    ) -> Result<(), Box<dyn std::error::Error>> {
1990        let config = PoolConfigBuilder::new().max_size(5).build()?;
1991        let factory = Arc::new(MockConnectionFactory);
1992        let pool = Pool::new(config, factory)?;
1993
1994        let removed = pool.health_check().await;
1995        assert_eq!(removed, 0);
1996        Ok(())
1997    }
1998
1999    // ==================== 生产 Bug 复现测试 ====================
2000
2001    /// 可追踪创建次数的连接工厂
2002    struct CountingFactory {
2003        count: AtomicU32,
2004    }
2005
2006    impl CountingFactory {
2007        fn new() -> Self {
2008            Self {
2009                count: AtomicU32::new(0),
2010            }
2011        }
2012        fn created_count(&self) -> u32 {
2013            self.count.load(Ordering::SeqCst)
2014        }
2015    }
2016
2017    #[async_trait]
2018    impl ConnectionFactory for CountingFactory {
2019        async fn create(&self) -> Result<Box<dyn Connection>, crate::DbError> {
2020            self.count.fetch_add(1, Ordering::SeqCst);
2021            Ok(Box::new(MockConnection::new()))
2022        }
2023    }
2024
2025    /// 生产 Bug 复现:release() 重置 created_at 导致连接永不过期
2026    ///
2027    /// 症状:生产环境运行 30 分钟后间歇性 "connection timeout"
2028    /// 根因:release() 中 created_at 被重置为 now(),max_lifetime 检查永远不触发
2029    /// 期望:超过 max_lifetime 的连接应被回收并创建新连接
2030    #[tokio::test]
2031    async fn test_production_bug_max_lifetime_never_expires(
2032    ) -> Result<(), Box<dyn std::error::Error>> {
2033        // 注意:PoolConfigBuilder::max_lifetime() 接受秒,这里需要毫秒级精度
2034        // 所以直接构造 PoolConfig
2035        let config = PoolConfig {
2036            max_size: 5,
2037            min_idle: 0,
2038            acquire_timeout: Duration::from_secs(30),
2039            idle_timeout: Duration::from_secs(600),
2040            max_lifetime: Duration::from_millis(100), // 100ms
2041            connection_timeout: Duration::from_secs(10),
2042            tls: None,
2043            query_timeout: None,
2044            max_rows: None,
2045            memory_limit: None,
2046            on_event: None,
2047            test_before_acquire: false,
2048            prewarm: false,
2049        };
2050        let factory = Arc::new(CountingFactory::new());
2051        let pool = Pool::new(config, factory.clone())?;
2052
2053        // 1. 创建连接
2054        let conn = pool.acquire().await?;
2055        assert_eq!(factory.created_count(), 1, "应创建 1 个连接");
2056
2057        // 2. 归还连接(bug:重置 created_at)
2058        pool.release(conn).await;
2059
2060        // 3. 等待超过 max_lifetime
2061        tokio::time::sleep(Duration::from_millis(150)).await;
2062
2063        // 4. 再次获取 — 应检测到连接过期,创建新连接
2064        let conn2 = pool.acquire().await?;
2065
2066        // 5. 验证:如果 bug 存在,factory.created_count() 仍为 1(连接被复用,未过期)
2067        //         如果修复,factory.created_count() 应为 2(旧连接过期,创建新连接)
2068        assert_eq!(
2069            factory.created_count(),
2070            2,
2071            "超过 max_lifetime 后应创建新连接(旧连接应被回收)"
2072        );
2073
2074        pool.release(conn2).await;
2075        Ok(())
2076    }
2077
2078    // ==================== PooledConnection::Drop 自动归还测试 ====================
2079
2080    /// 验证 PooledConnection drop 时自动归还连接到池
2081    ///
2082    /// 修复前:PooledConnection 未实现 Drop,drop 时连接丢失,池耗尽
2083    /// 修复后:Drop 时 spawn 异步 release,连接自动归还
2084    #[tokio::test]
2085    async fn test_drop_auto_release_connection() -> Result<(), Box<dyn std::error::Error>> {
2086        let config = PoolConfigBuilder::new().max_size(2).build()?;
2087        let factory = Arc::new(CountingFactory::new());
2088        let pool = Pool::new(config, factory.clone())?;
2089
2090        // 1. acquire 一个连接(不显式 release)
2091        {
2092            let _conn = pool.acquire().await?;
2093            assert_eq!(factory.created_count(), 1, "应创建 1 个连接");
2094            let status = pool.status().await;
2095            assert_eq!(status.active, 1, "active 应为 1");
2096            assert_eq!(status.idle, 0, "idle 应为 0");
2097            // _conn 在此 drop
2098        }
2099
2100        // 2. 等待 Drop spawn 的异步 release 完成
2101        tokio::time::sleep(Duration::from_millis(50)).await;
2102
2103        // 3. 验证连接已自动归还到 idle 队列
2104        let status = pool.status().await;
2105        assert_eq!(status.idle, 1, "Drop 后连接应自动归还,idle 应为 1");
2106        assert_eq!(status.active, 1, "total_count 应为 1");
2107        assert_eq!(factory.created_count(), 1, "应复用归还的连接,不创建新连接");
2108        Ok(())
2109    }
2110
2111    /// 验证 Drop 自动归还后,连接可被再次 acquire 复用
2112    #[tokio::test]
2113    async fn test_drop_auto_release_then_reuse() -> Result<(), Box<dyn std::error::Error>> {
2114        let config = PoolConfigBuilder::new().max_size(1).build()?;
2115        let factory = Arc::new(CountingFactory::new());
2116        let pool = Pool::new(config, factory.clone())?;
2117
2118        // max_size=1,如果 Drop 不归还,第二次 acquire 会超时
2119        {
2120            let _conn = pool.acquire().await?;
2121        }
2122
2123        // 等待 Drop spawn 的 release 完成
2124        tokio::time::sleep(Duration::from_millis(50)).await;
2125
2126        // 再次 acquire 应复用归还的连接,不创建新连接
2127        let conn = pool.acquire().await?;
2128        assert_eq!(factory.created_count(), 1, "应复用归还的连接,不创建新连接");
2129
2130        pool.release(conn).await;
2131        Ok(())
2132    }
2133
2134    /// 验证 into_inner 后 Drop 不归还(连接被消费)
2135    #[tokio::test]
2136    async fn test_into_inner_does_not_return_to_pool() -> Result<(), Box<dyn std::error::Error>> {
2137        let config = PoolConfigBuilder::new().max_size(2).build()?;
2138        let factory = Arc::new(CountingFactory::new());
2139        let pool = Pool::new(config, factory.clone())?;
2140
2141        let conn = pool.acquire().await?;
2142        assert_eq!(factory.created_count(), 1);
2143
2144        // into_inner 消费连接,pool 字段设为 None
2145        let _raw_conn = conn.into_inner();
2146
2147        // 等待一段时间,确保不会有 Drop spawn
2148        tokio::time::sleep(Duration::from_millis(50)).await;
2149
2150        let status = pool.status().await;
2151        assert_eq!(status.idle, 0, "into_inner 后连接不应归还");
2152        assert_eq!(status.active, 1, "total_count 仍为 1(连接被外部持有)");
2153        Ok(())
2154    }
2155
2156    /// 验证显式 release 后 Drop 不会重复归还
2157    #[tokio::test]
2158    async fn test_explicit_release_no_double_return() -> Result<(), Box<dyn std::error::Error>> {
2159        let config = PoolConfigBuilder::new().max_size(2).build()?;
2160        let factory = Arc::new(CountingFactory::new());
2161        let pool = Pool::new(config, factory.clone())?;
2162
2163        let conn = pool.acquire().await?;
2164        pool.release(conn).await;
2165
2166        let status = pool.status().await;
2167        assert_eq!(status.idle, 1, "release 后 idle 应为 1");
2168
2169        // 再次 acquire + release 验证不会重复
2170        let conn = pool.acquire().await?;
2171        pool.release(conn).await;
2172
2173        let status = pool.status().await;
2174        assert_eq!(status.idle, 1, "再次 release 后 idle 仍应为 1(不重复)");
2175        assert_eq!(status.active, 1, "total_count 应为 1");
2176        Ok(())
2177    }
2178
2179    // ========================================================================
2180    // G-SX-4:query_stream 游标流式查询测试
2181    // ========================================================================
2182
2183    /// 带预设行数据的模拟连接,用于测试 `query_stream` 默认实现。
2184    struct CursorMockConn {
2185        rows: QueryRows,
2186        call_count: usize,
2187    }
2188
2189    impl CursorMockConn {
2190        fn new(rows: QueryRows) -> Self {
2191            Self {
2192                rows,
2193                call_count: 0,
2194            }
2195        }
2196    }
2197
2198    impl Connection for CursorMockConn {
2199        fn execute<'a>(
2200            &'a mut self,
2201            _sql: &'a str,
2202        ) -> Pin<Box<dyn Future<Output = Result<u64, crate::DbError>> + Send + 'a>> {
2203            Box::pin(async move { Ok(1) })
2204        }
2205
2206        fn query<'a>(
2207            &'a mut self,
2208            _sql: &'a str,
2209        ) -> Pin<Box<dyn Future<Output = Result<QueryRows, crate::DbError>> + Send + 'a>> {
2210            Box::pin(async move {
2211                self.call_count += 1;
2212                Ok(self.rows.clone())
2213            })
2214        }
2215
2216        fn begin_transaction<'a>(
2217            &'a mut self,
2218        ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
2219            Box::pin(async move { Ok(()) })
2220        }
2221
2222        fn commit<'a>(
2223            &'a mut self,
2224        ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
2225            Box::pin(async move { Ok(()) })
2226        }
2227
2228        fn rollback<'a>(
2229            &'a mut self,
2230        ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
2231            Box::pin(async move { Ok(()) })
2232        }
2233
2234        fn is_connected(&self) -> bool {
2235            true
2236        }
2237
2238        fn ping<'a>(&'a mut self) -> Pin<Box<dyn Future<Output = bool> + Send + 'a>> {
2239            Box::pin(async move { true })
2240        }
2241
2242        fn close<'a>(
2243            &'a mut self,
2244        ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
2245            Box::pin(async move { Ok(()) })
2246        }
2247    }
2248
2249    /// 模拟游标适配器:覆盖 `query_stream` 以逐行 yield,而非全量收集。
2250    struct CursorOverrideMockConn {
2251        rows: Vec<crate::value::Value>,
2252        yielded: usize,
2253    }
2254
2255    impl CursorOverrideMockConn {
2256        fn new(rows: Vec<crate::value::Value>) -> Self {
2257            Self { rows, yielded: 0 }
2258        }
2259    }
2260
2261    impl Connection for CursorOverrideMockConn {
2262        fn execute<'a>(
2263            &'a mut self,
2264            _sql: &'a str,
2265        ) -> Pin<Box<dyn Future<Output = Result<u64, crate::DbError>> + Send + 'a>> {
2266            Box::pin(async move { Ok(1) })
2267        }
2268
2269        fn query<'a>(
2270            &'a mut self,
2271            _sql: &'a str,
2272        ) -> Pin<Box<dyn Future<Output = Result<QueryRows, crate::DbError>> + Send + 'a>> {
2273            // 全量收集实现(不应被 cursor override 调用)
2274            Box::pin(async move {
2275                Ok(self
2276                    .rows
2277                    .iter()
2278                    .map(|v| {
2279                        let mut m = std::collections::HashMap::new();
2280                        m.insert("v".to_string(), v.clone());
2281                        m
2282                    })
2283                    .collect())
2284            })
2285        }
2286
2287        /// G-SX-4:覆盖 query_stream,逐行 yield 模拟真游标
2288        fn query_stream<'a>(
2289            &'a mut self,
2290            _sql: &'a str,
2291        ) -> Pin<Box<dyn futures::Stream<Item = QueryStreamItem> + Send + 'a>> {
2292            Box::pin(futures::stream::iter(
2293                self.rows
2294                    .iter()
2295                    .enumerate()
2296                    .map(|(i, v)| {
2297                        self.yielded = i + 1;
2298                        let mut m = std::collections::HashMap::new();
2299                        m.insert("v".to_string(), v.clone());
2300                        Ok(m)
2301                    })
2302                    .collect::<Vec<_>>(),
2303            ))
2304        }
2305
2306        fn begin_transaction<'a>(
2307            &'a mut self,
2308        ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
2309            Box::pin(async move { Ok(()) })
2310        }
2311
2312        fn commit<'a>(
2313            &'a mut self,
2314        ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
2315            Box::pin(async move { Ok(()) })
2316        }
2317
2318        fn rollback<'a>(
2319            &'a mut self,
2320        ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
2321            Box::pin(async move { Ok(()) })
2322        }
2323
2324        fn is_connected(&self) -> bool {
2325            true
2326        }
2327
2328        fn ping<'a>(&'a mut self) -> Pin<Box<dyn Future<Output = bool> + Send + 'a>> {
2329            Box::pin(async move { true })
2330        }
2331
2332        fn close<'a>(
2333            &'a mut self,
2334        ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
2335            Box::pin(async move { Ok(()) })
2336        }
2337    }
2338
2339    /// G-SX-4 测试 1:默认 query_stream 逐行 yield 全量结果
2340    #[tokio::test]
2341    async fn test_query_stream_default_impl_yields_all_rows() {
2342        use futures::StreamExt;
2343        let rows: QueryRows = vec![
2344            std::collections::HashMap::from([
2345                ("id".to_string(), crate::value::Value::I64(1)),
2346                (
2347                    "name".to_string(),
2348                    crate::value::Value::String("alice".to_string()),
2349                ),
2350            ]),
2351            std::collections::HashMap::from([
2352                ("id".to_string(), crate::value::Value::I64(2)),
2353                (
2354                    "name".to_string(),
2355                    crate::value::Value::String("bob".to_string()),
2356                ),
2357            ]),
2358            std::collections::HashMap::from([
2359                ("id".to_string(), crate::value::Value::I64(3)),
2360                (
2361                    "name".to_string(),
2362                    crate::value::Value::String("carol".to_string()),
2363                ),
2364            ]),
2365        ];
2366        let mut conn = CursorMockConn::new(rows);
2367        let mut stream = conn.query_stream("SELECT id, name FROM users");
2368        let mut received: Vec<QueryStreamItem> = Vec::new();
2369        while let Some(item) = stream.next().await {
2370            received.push(item);
2371        }
2372        assert_eq!(received.len(), 3, "应收到 3 行");
2373        assert!(received.iter().all(|r| r.is_ok()), "所有项应为 Ok");
2374        drop(stream);
2375        assert_eq!(conn.call_count, 1, "默认实现应调用 query() 一次");
2376    }
2377
2378    /// G-SX-4 测试 2:默认 query_stream 空结果集
2379    #[tokio::test]
2380    async fn test_query_stream_default_empty_result() {
2381        use futures::StreamExt;
2382        let mut conn = CursorMockConn::new(Vec::new());
2383        let mut stream = conn.query_stream("SELECT * FROM empty_table");
2384        let mut count = 0;
2385        while let Some(_item) = stream.next().await {
2386            count += 1;
2387        }
2388        assert_eq!(count, 0, "空结果集应产生 0 项");
2389    }
2390
2391    /// G-SX-4 测试 3:默认 query_stream 错误传播
2392    #[tokio::test]
2393    async fn test_query_stream_default_error_propagation() {
2394        use futures::StreamExt;
2395        // 创建一个会返回错误的 mock
2396        struct ErrorMockConn;
2397        impl Connection for ErrorMockConn {
2398            fn execute<'a>(
2399                &'a mut self,
2400                _sql: &'a str,
2401            ) -> Pin<Box<dyn Future<Output = Result<u64, crate::DbError>> + Send + 'a>>
2402            {
2403                Box::pin(async move { Ok(1) })
2404            }
2405            fn query<'a>(
2406                &'a mut self,
2407                _sql: &'a str,
2408            ) -> Pin<Box<dyn Future<Output = Result<QueryRows, crate::DbError>> + Send + 'a>>
2409            {
2410                Box::pin(async move { Err(crate::DbError::Internal("query failed".to_string())) })
2411            }
2412            fn begin_transaction<'a>(
2413                &'a mut self,
2414            ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
2415                Box::pin(async move { Ok(()) })
2416            }
2417            fn commit<'a>(
2418                &'a mut self,
2419            ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
2420                Box::pin(async move { Ok(()) })
2421            }
2422            fn rollback<'a>(
2423                &'a mut self,
2424            ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
2425                Box::pin(async move { Ok(()) })
2426            }
2427            fn is_connected(&self) -> bool {
2428                true
2429            }
2430            fn ping<'a>(&'a mut self) -> Pin<Box<dyn Future<Output = bool> + Send + 'a>> {
2431                Box::pin(async move { true })
2432            }
2433            fn close<'a>(
2434                &'a mut self,
2435            ) -> Pin<Box<dyn Future<Output = Result<(), crate::DbError>> + Send + 'a>> {
2436                Box::pin(async move { Ok(()) })
2437            }
2438        }
2439        let mut conn = ErrorMockConn;
2440        let mut stream = conn.query_stream("SELECT * FROM bad_table");
2441        let item = stream.next().await;
2442        assert!(item.is_some(), "应产生一项");
2443        assert!(item.unwrap().is_err(), "该项应为 Err");
2444    }
2445
2446    /// G-SX-4 测试 4:覆盖 query_stream 的适配器逐行 yield(模拟真游标)
2447    #[tokio::test]
2448    async fn test_query_stream_override_yields_rows_one_by_one() {
2449        use futures::StreamExt;
2450        let rows = vec![
2451            crate::value::Value::I64(10),
2452            crate::value::Value::I64(20),
2453            crate::value::Value::I64(30),
2454            crate::value::Value::I64(40),
2455            crate::value::Value::I64(50),
2456        ];
2457        let mut conn = CursorOverrideMockConn::new(rows);
2458        let values: Vec<i64> = {
2459            let mut stream = conn.query_stream("SELECT v FROM seq");
2460            let mut vals: Vec<i64> = Vec::new();
2461            while let Some(Ok(row)) = stream.next().await {
2462                if let crate::value::Value::I64(v) = row.get("v").unwrap() {
2463                    vals.push(*v);
2464                }
2465            }
2466            vals
2467        };
2468        assert_eq!(values, vec![10, 20, 30, 40, 50], "应按顺序收到全部 5 行");
2469        assert_eq!(conn.yielded, 5, "应逐行 yield 5 次(真游标覆盖)");
2470    }
2471
2472    /// G-SX-4 测试 5:覆盖 query_stream 提前 drop 流(消费者中断)
2473    #[tokio::test]
2474    async fn test_query_stream_override_early_drop() {
2475        use futures::StreamExt;
2476        let rows = vec![
2477            crate::value::Value::I64(1),
2478            crate::value::Value::I64(2),
2479            crate::value::Value::I64(3),
2480        ];
2481        let mut conn = CursorOverrideMockConn::new(rows);
2482        {
2483            let mut stream = conn.query_stream("SELECT v FROM seq");
2484            let first = stream.next().await;
2485            assert!(first.is_some(), "第一项应存在");
2486            // 提前 drop stream — 模拟消费者中断
2487            drop(stream);
2488        }
2489        // 连接仍可用
2490        assert!(conn.is_connected(), "提前 drop 流后连接仍应可用");
2491    }
2492
2493    /// TASK-021:连接池预热测试
2494    #[tokio::test]
2495    async fn test_pool_prewarm() -> Result<(), Box<dyn std::error::Error>> {
2496        use std::sync::atomic::AtomicU32;
2497
2498        // 创建可计数的连接工厂
2499        let create_count = Arc::new(AtomicU32::new(0));
2500        let create_count_clone = create_count.clone();
2501
2502        struct CountingFactory {
2503            count: Arc<AtomicU32>,
2504        }
2505
2506        #[async_trait]
2507        impl ConnectionFactory for CountingFactory {
2508            async fn create(&self) -> Result<Box<dyn Connection>, crate::DbError> {
2509                self.count.fetch_add(1, Ordering::SeqCst);
2510                Ok(Box::new(MockConnection::new()))
2511            }
2512        }
2513
2514        // 配置:max_size=10, min_idle=5, prewarm=true
2515        let config = PoolConfigBuilder::new()
2516            .max_size(10)
2517            .min_idle(5)
2518            .prewarm(true)
2519            .build()?;
2520
2521        let factory = Arc::new(CountingFactory {
2522            count: create_count_clone,
2523        });
2524
2525        let pool = Pool::new(config, factory)?;
2526
2527        // 预热前:空闲连接为 0
2528        let status_before = pool.status().await;
2529        assert_eq!(status_before.idle, 0, "预热前 idle 应为 0");
2530
2531        // 执行预热
2532        pool.prewarm().await;
2533
2534        // 预热后:空闲连接应 >= min_idle(5)
2535        let status_after = pool.status().await;
2536        assert!(
2537            status_after.idle >= 5,
2538            "预热后 idle 应 >= 5,实际: {}",
2539            status_after.idle
2540        );
2541
2542        // 验证工厂被调用了 5 次(min_idle)
2543        assert_eq!(
2544            create_count.load(Ordering::SeqCst),
2545            5,
2546            "工厂应被调用 5 次(min_idle)"
2547        );
2548
2549        Ok(())
2550    }
2551
2552    /// TASK-021:预热失败不阻断池创建
2553    #[tokio::test]
2554    async fn test_pool_prewarm_failure_non_blocking() -> Result<(), Box<dyn std::error::Error>> {
2555        use std::sync::atomic::AtomicBool;
2556
2557        struct FailingFactory {
2558            failed: Arc<AtomicBool>,
2559        }
2560
2561        #[async_trait]
2562        impl ConnectionFactory for FailingFactory {
2563            async fn create(&self) -> Result<Box<dyn Connection>, crate::DbError> {
2564                self.failed.store(true, Ordering::SeqCst);
2565                // 模拟连接失败
2566                Err(crate::DbError::Internal(
2567                    "simulated connection failure".to_string(),
2568                ))
2569            }
2570        }
2571
2572        let failed = Arc::new(AtomicBool::new(false));
2573        let mut config = PoolConfigBuilder::new()
2574            .max_size(10)
2575            .min_idle(3)
2576            .prewarm(true)
2577            .build()?;
2578        config.connection_timeout = std::time::Duration::from_secs(1); // 缩短超时以加快测试
2579
2580        let factory = Arc::new(FailingFactory {
2581            failed: failed.clone(),
2582        });
2583
2584        // 池创建应成功(即使预热失败)
2585        let pool = Pool::new(config, factory)?;
2586        pool.prewarm().await; // 预热失败不应 panic
2587
2588        // 验证工厂被调用了 3 次(尝试预热 3 个连接)
2589        assert!(failed.load(Ordering::SeqCst), "工厂应被调用且失败");
2590
2591        // 池仍然可用(acquire 会尝试创建新连接)
2592        let status = pool.status().await;
2593        assert_eq!(status.max, 10, "池配置应正常");
2594
2595        Ok(())
2596    }
2597
2598    /// TASK-021:prewarm=false 时预热不执行
2599    #[tokio::test]
2600    async fn test_pool_prewarm_disabled() -> Result<(), Box<dyn std::error::Error>> {
2601        use std::sync::atomic::AtomicU32;
2602
2603        let create_count = Arc::new(AtomicU32::new(0));
2604        let create_count_clone = create_count.clone();
2605
2606        struct CountingFactory {
2607            count: Arc<AtomicU32>,
2608        }
2609
2610        #[async_trait]
2611        impl ConnectionFactory for CountingFactory {
2612            async fn create(&self) -> Result<Box<dyn Connection>, crate::DbError> {
2613                self.count.fetch_add(1, Ordering::SeqCst);
2614                Ok(Box::new(MockConnection::new()))
2615            }
2616        }
2617
2618        // 配置:prewarm=false
2619        let config = PoolConfigBuilder::new()
2620            .max_size(10)
2621            .min_idle(5)
2622            .prewarm(false) // 禁用预热
2623            .build()?;
2624
2625        let factory = Arc::new(CountingFactory {
2626            count: create_count_clone,
2627        });
2628
2629        let pool = Pool::new(config, factory)?;
2630        pool.prewarm().await; // 应直接返回,不创建连接
2631
2632        // 验证工厂未被调用
2633        assert_eq!(
2634            create_count.load(Ordering::SeqCst),
2635            0,
2636            "prewarm=false 时工厂不应被调用"
2637        );
2638
2639        let status = pool.status().await;
2640        assert_eq!(status.idle, 0, "idle 应为 0");
2641
2642        Ok(())
2643    }
2644
2645    /// Prometheus 风格统计:acquire/release 计数与连接创建计数
2646    #[tokio::test]
2647    async fn test_pool_metrics_acquire_release() -> Result<(), Box<dyn std::error::Error>> {
2648        let config = PoolConfigBuilder::new().max_size(10).build()?;
2649        let pool = Pool::new(config, Arc::new(MockConnectionFactory))?;
2650
2651        let metrics = pool.pool_metrics();
2652        assert_eq!(metrics.acquire_count, 0);
2653        assert_eq!(metrics.release_count, 0);
2654        assert_eq!(metrics.connection_created_count, 0);
2655
2656        let conn = pool.acquire().await?;
2657        let metrics = pool.pool_metrics();
2658        assert_eq!(metrics.acquire_count, 1);
2659        assert_eq!(metrics.connection_created_count, 1);
2660        assert_eq!(metrics.acquire_failed_count, 0);
2661
2662        pool.release(conn).await;
2663        let metrics = pool.pool_metrics();
2664        assert_eq!(metrics.release_count, 1);
2665        // 连接归还到空闲队列,未被关闭
2666        assert_eq!(metrics.connection_closed_count, 0);
2667
2668        Ok(())
2669    }
2670
2671    /// Prometheus 风格统计:获取失败计数(工厂创建连接失败)
2672    #[tokio::test]
2673    async fn test_pool_metrics_acquire_failed() -> Result<(), Box<dyn std::error::Error>> {
2674        struct FailingFactory;
2675
2676        #[async_trait]
2677        impl ConnectionFactory for FailingFactory {
2678            async fn create(&self) -> Result<Box<dyn Connection>, crate::DbError> {
2679                Err(crate::DbError::Internal("simulated failure".to_string()))
2680            }
2681        }
2682
2683        let config = PoolConfigBuilder::new().max_size(10).build()?;
2684        let pool = Pool::new(config, Arc::new(FailingFactory))?;
2685
2686        let result = pool.acquire().await;
2687        assert!(result.is_err());
2688
2689        let metrics = pool.pool_metrics();
2690        assert_eq!(metrics.acquire_failed_count, 1);
2691        assert_eq!(metrics.acquire_count, 0);
2692
2693        Ok(())
2694    }
2695
2696    /// Prometheus 风格统计:连接关闭计数(close_all 后空闲连接被关闭)
2697    #[tokio::test]
2698    async fn test_pool_metrics_connection_closed() -> Result<(), Box<dyn std::error::Error>> {
2699        let config = PoolConfigBuilder::new().max_size(10).build()?;
2700        let pool = Pool::new(config, Arc::new(MockConnectionFactory))?;
2701
2702        let conn = pool.acquire().await?;
2703        pool.release(conn).await;
2704
2705        let status = pool.status().await;
2706        assert_eq!(status.idle, 1);
2707
2708        pool.close_all().await;
2709
2710        let metrics = pool.pool_metrics();
2711        assert_eq!(metrics.connection_closed_count, 1);
2712        assert_eq!(metrics.connection_created_count, 1);
2713
2714        Ok(())
2715    }
2716
2717    /// Prometheus 风格统计:平均获取等待时长计算
2718    #[test]
2719    fn test_pool_metrics_average_wait_time() {
2720        let metrics = PoolMetrics {
2721            acquire_count: 4,
2722            acquire_failed_count: 1,
2723            acquire_wait_time: Duration::from_millis(200),
2724            release_count: 4,
2725            connection_created_count: 2,
2726            connection_closed_count: 0,
2727        };
2728        assert_eq!(
2729            metrics.average_acquire_wait_time(),
2730            Duration::from_millis(50)
2731        );
2732
2733        // 无成功获取时平均等待时长为 0
2734        let empty = PoolMetrics::default();
2735        assert_eq!(empty.average_acquire_wait_time(), Duration::ZERO);
2736    }
2737}