use crate::client::config::PoolConfig;
use chrono::{DateTime, Utc};
use sqlx::postgres::{PgPool, PgPoolOptions};
use std::time::Duration;
#[derive(Debug, Clone)]
pub struct ConnectionPoolSnapshot {
pub client_name: String,
pub pool_size: u32,
pub idle_connections: u32,
pub active_connections: u32,
pub max_connections: u32,
pub recorded_at: DateTime<Utc>,
}
impl ConnectionPoolSnapshot {
pub fn new(client_name: String, pool: &PgPool) -> Self {
let pool_size: u32 = pool.size();
let idle: u32 = pool.num_idle().try_into().unwrap_or_default();
let max_connections: u32 = pool.options().get_max_connections();
let active_connections: u32 = pool_size.saturating_sub(idle);
Self {
client_name,
pool_size,
idle_connections: idle,
active_connections,
max_connections,
recorded_at: Utc::now(),
}
}
}
#[derive(Clone, Debug)]
pub struct ConnectionPoolManager {
config: PoolConfig,
max_lifetime: Duration,
test_before_acquire: bool,
}
impl Default for ConnectionPoolManager {
fn default() -> Self {
Self {
config: PoolConfig::default(),
max_lifetime: Duration::from_secs(1800),
test_before_acquire: false,
}
}
}
impl ConnectionPoolManager {
pub fn new(config: PoolConfig) -> Self {
Self {
config,
..Default::default()
}
}
pub fn with_max_lifetime(mut self, max_lifetime: Duration) -> Self {
self.max_lifetime = max_lifetime;
self
}
pub fn with_test_before_acquire(mut self, test_before_acquire: bool) -> Self {
self.test_before_acquire = test_before_acquire;
self
}
pub async fn connect(&self, uri: &str) -> Result<PgPool, sqlx::Error> {
self.build_options().connect(uri).await
}
pub fn build_options(&self) -> PgPoolOptions {
PgPoolOptions::new()
.max_connections(self.config.max_connections)
.min_connections(self.config.min_connections)
.acquire_timeout(self.config.connection_timeout)
.idle_timeout(Some(self.config.idle_timeout))
.max_lifetime(Some(self.max_lifetime))
.test_before_acquire(self.test_before_acquire)
}
}