use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::time::Duration;
use crate::Result;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConnectionState {
Disconnected,
Connecting,
Connected,
Reconnecting,
}
impl std::fmt::Display for ConnectionState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ConnectionState::Disconnected => write!(f, "disconnected"),
ConnectionState::Connecting => write!(f, "connecting"),
ConnectionState::Connected => write!(f, "connected"),
ConnectionState::Reconnecting => write!(f, "reconnecting"),
}
}
}
#[derive(Debug, Clone)]
pub enum ConnectionEvent {
Connected,
Disconnected { reason: String },
Reconnecting { attempt: u32 },
Reconnected,
ReconnectFailed { error: String },
}
pub trait ConnectionObserver: Send + Sync {
fn on_state_change(&self, old_state: ConnectionState, new_state: ConnectionState);
fn on_event(&self, event: ConnectionEvent);
}
#[derive(Debug, Clone)]
pub struct PoolConfig {
pub min_connections: u32,
pub max_connections: u32,
pub idle_timeout: Option<Duration>,
pub acquire_timeout: Duration,
pub max_lifetime: Option<Duration>,
}
impl Default for PoolConfig {
fn default() -> Self {
Self {
min_connections: 1,
max_connections: 10,
idle_timeout: Some(Duration::from_secs(300)),
acquire_timeout: Duration::from_secs(30),
max_lifetime: Some(Duration::from_secs(1800)),
}
}
}
impl PoolConfig {
pub fn new() -> Self {
Self::default()
}
pub fn with_min_connections(mut self, min: u32) -> Self {
self.min_connections = min;
self
}
pub fn with_max_connections(mut self, max: u32) -> Self {
self.max_connections = max;
self
}
pub fn with_idle_timeout(mut self, timeout: Duration) -> Self {
self.idle_timeout = Some(timeout);
self
}
pub fn without_idle_timeout(mut self) -> Self {
self.idle_timeout = None;
self
}
pub fn with_acquire_timeout(mut self, timeout: Duration) -> Self {
self.acquire_timeout = timeout;
self
}
pub fn with_max_lifetime(mut self, lifetime: Duration) -> Self {
self.max_lifetime = Some(lifetime);
self
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct PoolStats {
pub connections_created: u64,
pub connections_closed: u64,
pub active_connections: u32,
pub idle_connections: u32,
pub acquire_requests: u64,
pub acquire_timeouts: u64,
}
impl PoolStats {
pub fn total_connections(&self) -> u32 {
self.active_connections + self.idle_connections
}
}
#[async_trait]
pub trait ConnectionPool: Send + Sync {
fn config(&self) -> &PoolConfig;
fn stats(&self) -> PoolStats;
async fn resize(&mut self, min: u32, max: u32) -> Result<()>;
async fn shrink(&mut self) -> Result<u32>;
async fn close(&mut self) -> Result<()>;
}