use std::fmt;
use std::sync::Arc;
use std::time::Duration;
use futures_core::future::BoxFuture;
use crate::error::Result;
use crate::pool::health::HealthCheckStrategy;
use crate::Connection;
pub type ConnectCallback = Arc<dyn Fn(&mut Connection) -> BoxFuture<'_, Result<()>> + Send + Sync>;
pub type AcquireCallback =
Arc<dyn Fn(&mut Connection) -> BoxFuture<'_, Result<bool>> + Send + Sync>;
pub type ReleaseCallback =
Arc<dyn Fn(&mut Connection) -> BoxFuture<'_, Result<bool>> + Send + Sync>;
#[derive(Clone)]
pub struct PoolConfig {
pub max_connections: usize,
pub min_connections: usize,
pub connect_timeout: Duration,
pub idle_timeout: Option<Duration>,
pub max_lifetime: Option<Duration>,
pub health_check: HealthCheckStrategy,
pub acquire_timeout: Duration,
pub after_connect: Option<ConnectCallback>,
pub before_acquire: Option<AcquireCallback>,
pub after_release: Option<ReleaseCallback>,
}
impl fmt::Debug for PoolConfig {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("PoolConfig")
.field("max_connections", &self.max_connections)
.field("min_connections", &self.min_connections)
.field("connect_timeout", &self.connect_timeout)
.field("idle_timeout", &self.idle_timeout)
.field("max_lifetime", &self.max_lifetime)
.field("health_check", &self.health_check)
.field("acquire_timeout", &self.acquire_timeout)
.field("after_connect", &self.after_connect.as_ref().map(|_| ".."))
.field(
"before_acquire",
&self.before_acquire.as_ref().map(|_| ".."),
)
.field("after_release", &self.after_release.as_ref().map(|_| ".."))
.finish()
}
}
impl Default for PoolConfig {
fn default() -> Self {
Self {
max_connections: num_cpus(),
min_connections: 1,
connect_timeout: Duration::from_secs(10),
idle_timeout: Some(Duration::from_secs(600)),
max_lifetime: Some(Duration::from_secs(3600)),
health_check: HealthCheckStrategy::Fast,
acquire_timeout: Duration::from_secs(30),
after_connect: None,
before_acquire: None,
after_release: None,
}
}
}
impl PoolConfig {
pub fn new() -> Self {
Self::default()
}
pub fn max_connections(mut self, n: usize) -> Self {
self.max_connections = n;
self
}
pub fn min_connections(mut self, n: usize) -> Self {
self.min_connections = n;
self
}
pub fn connect_timeout(mut self, timeout: Duration) -> Self {
self.connect_timeout = timeout;
self
}
pub fn idle_timeout(mut self, timeout: Option<Duration>) -> Self {
self.idle_timeout = timeout;
self
}
pub fn max_lifetime(mut self, lifetime: Option<Duration>) -> Self {
self.max_lifetime = lifetime;
self
}
pub fn health_check(mut self, strategy: HealthCheckStrategy) -> Self {
self.health_check = strategy;
self
}
pub fn acquire_timeout(mut self, timeout: Duration) -> Self {
self.acquire_timeout = timeout;
self
}
pub fn after_connect<F>(mut self, callback: F) -> Self
where
F: Fn(&mut Connection) -> BoxFuture<'_, Result<()>> + Send + Sync + 'static,
{
self.after_connect = Some(Arc::new(callback));
self
}
pub fn before_acquire<F>(mut self, callback: F) -> Self
where
F: Fn(&mut Connection) -> BoxFuture<'_, Result<bool>> + Send + Sync + 'static,
{
self.before_acquire = Some(Arc::new(callback));
self
}
pub fn after_release<F>(mut self, callback: F) -> Self
where
F: Fn(&mut Connection) -> BoxFuture<'_, Result<bool>> + Send + Sync + 'static,
{
self.after_release = Some(Arc::new(callback));
self
}
}
fn num_cpus() -> usize {
std::thread::available_parallelism().map_or(8, |n| n.get() * 2)
}