Skip to main content

do_memory_storage_turso/pool/
config.rs

1//! Connection pool configuration and statistics
2//!
3//! Provides configuration structs, statistics tracking, and connection guards.
4
5use do_memory_core::{Error, Result};
6use libsql::Connection;
7use parking_lot::RwLock;
8use std::sync::Arc;
9use std::time::Duration;
10use tokio::sync::OwnedSemaphorePermit;
11
12/// Configuration for connection pool
13#[derive(Debug, Clone)]
14pub struct PoolConfig {
15    /// Maximum number of concurrent connections
16    pub max_connections: usize,
17    /// Maximum time to wait for a connection (seconds)
18    pub connection_timeout: Duration,
19    /// Enable connection health checks
20    pub enable_health_check: bool,
21    /// Health check timeout
22    pub health_check_timeout: Duration,
23}
24
25impl Default for PoolConfig {
26    fn default() -> Self {
27        Self {
28            max_connections: 10,
29            connection_timeout: Duration::from_secs(5),
30            enable_health_check: true,
31            health_check_timeout: Duration::from_secs(2),
32        }
33    }
34}
35
36/// Pool statistics for monitoring
37#[derive(Debug, Clone, Default)]
38pub struct PoolStatistics {
39    /// Total connections created
40    pub total_created: usize,
41    /// Total connections that passed health check
42    pub total_health_checks_passed: usize,
43    /// Total connections failed health check
44    pub total_health_checks_failed: usize,
45    /// Current number of active (checked out) connections
46    pub active_connections: usize,
47    /// Total checkout wait time (milliseconds)
48    pub total_wait_time_ms: u64,
49    /// Number of checkouts
50    pub total_checkouts: usize,
51    /// Average wait time per checkout (milliseconds)
52    pub avg_wait_time_ms: u64,
53}
54
55impl PoolStatistics {
56    pub fn update_averages(&mut self) {
57        if self.total_checkouts > 0 {
58            self.avg_wait_time_ms = self.total_wait_time_ms / self.total_checkouts as u64;
59        }
60    }
61}
62
63/// A guard that returns a permit to the pool when dropped
64#[derive(Debug)]
65pub struct PooledConnection {
66    pub(super) connection: Option<Connection>,
67    pub(super) _permit: OwnedSemaphorePermit,
68    pub(super) stats: Arc<RwLock<PoolStatistics>>,
69}
70
71impl PooledConnection {
72    /// Get a reference to the underlying connection
73    pub fn connection(&self) -> Option<&Connection> {
74        self.connection.as_ref()
75    }
76
77    /// Take ownership of the connection
78    pub fn into_inner(mut self) -> Result<Connection> {
79        self.connection
80            .take()
81            .ok_or_else(|| Error::Storage("Connection already taken".to_string()))
82    }
83}
84
85impl Drop for PooledConnection {
86    fn drop(&mut self) {
87        // Decrement active connections when the guard is dropped
88        // Using parking_lot's RwLock which supports blocking operations in Drop
89        let mut stats = self.stats.write();
90        if stats.active_connections > 0 {
91            stats.active_connections -= 1;
92        }
93    }
94}