use do_memory_core::{Error, Result};
use libsql::Connection;
use parking_lot::RwLock;
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::OwnedSemaphorePermit;
#[derive(Debug, Clone)]
pub struct PoolConfig {
pub max_connections: usize,
pub connection_timeout: Duration,
pub enable_health_check: bool,
pub health_check_timeout: Duration,
}
impl Default for PoolConfig {
fn default() -> Self {
Self {
max_connections: 10,
connection_timeout: Duration::from_secs(5),
enable_health_check: true,
health_check_timeout: Duration::from_secs(2),
}
}
}
#[derive(Debug, Clone, Default)]
pub struct PoolStatistics {
pub total_created: usize,
pub total_health_checks_passed: usize,
pub total_health_checks_failed: usize,
pub active_connections: usize,
pub total_wait_time_ms: u64,
pub total_checkouts: usize,
pub avg_wait_time_ms: u64,
}
impl PoolStatistics {
pub fn update_averages(&mut self) {
if self.total_checkouts > 0 {
self.avg_wait_time_ms = self.total_wait_time_ms / self.total_checkouts as u64;
}
}
}
#[derive(Debug)]
pub struct PooledConnection {
pub(super) connection: Option<Connection>,
pub(super) _permit: OwnedSemaphorePermit,
pub(super) stats: Arc<RwLock<PoolStatistics>>,
}
impl PooledConnection {
pub fn connection(&self) -> Option<&Connection> {
self.connection.as_ref()
}
pub fn into_inner(mut self) -> Result<Connection> {
self.connection
.take()
.ok_or_else(|| Error::Storage("Connection already taken".to_string()))
}
}
impl Drop for PooledConnection {
fn drop(&mut self) {
let mut stats = self.stats.write();
if stats.active_connections > 0 {
stats.active_connections -= 1;
}
}
}