use crate::{Manager, Pool};
use std::marker::PhantomData;
use std::time::Duration;
const DEFAULT_MAX_IDLE_CONNS: u64 = 2;
const DEFAULT_MAX_OPEN_CONNS: u64 = 10;
const DEFAULT_BAD_CONN_RETRIES: u32 = 2;
pub(crate) struct Config {
pub max_open: u64,
pub max_idle: u64,
pub max_lifetime: Option<Duration>,
pub max_idle_lifetime: Option<Duration>,
pub clean_rate: Duration,
pub max_bad_conn_retries: u32,
pub get_timeout: Option<Duration>,
pub health_check_interval: Option<Duration>,
pub health_check: bool,
}
impl Config {
pub fn split(self) -> (ShareConfig, InternalConfig) {
let share = ShareConfig {
clean_rate: self.clean_rate,
max_bad_conn_retries: self.max_bad_conn_retries,
get_timeout: self.get_timeout,
health_check: self.health_check,
health_check_interval: self.health_check_interval,
};
let internal = InternalConfig {
max_open: self.max_open,
max_idle: self.max_idle,
max_lifetime: self.max_lifetime,
max_idle_lifetime: self.max_idle_lifetime,
};
(share, internal)
}
}
pub(crate) struct ShareConfig {
pub clean_rate: Duration,
pub max_bad_conn_retries: u32,
pub get_timeout: Option<Duration>,
pub health_check: bool,
pub health_check_interval: Option<Duration>,
}
pub(crate) struct InternalConfig {
pub max_open: u64,
pub max_idle: u64,
pub max_lifetime: Option<Duration>,
pub max_idle_lifetime: Option<Duration>,
}
pub struct Builder<M> {
max_open: u64,
max_idle: Option<u64>,
max_lifetime: Option<Duration>,
max_idle_lifetime: Option<Duration>,
clean_rate: Duration,
max_bad_conn_retries: u32,
get_timeout: Option<Duration>,
health_check_interval: Option<Duration>,
health_check: bool,
_keep: PhantomData<M>,
}
impl<M> Default for Builder<M> {
fn default() -> Self {
Self {
max_open: DEFAULT_MAX_OPEN_CONNS,
max_idle: None,
max_lifetime: None,
max_idle_lifetime: None,
clean_rate: Duration::from_secs(1),
max_bad_conn_retries: DEFAULT_BAD_CONN_RETRIES,
get_timeout: Some(Duration::from_secs(30)),
_keep: PhantomData,
health_check: true,
health_check_interval: None,
}
}
}
impl<M: Manager> Builder<M> {
pub fn new() -> Self {
Default::default()
}
pub fn max_open(mut self, max_open: u64) -> Self {
self.max_open = max_open;
self
}
pub fn max_idle(mut self, max_idle: u64) -> Self {
self.max_idle = Some(max_idle);
self
}
pub fn test_on_check_out(mut self, health_check: bool) -> Builder<M> {
self.health_check = health_check;
self
}
pub fn max_lifetime(mut self, max_lifetime: Option<Duration>) -> Self {
assert_ne!(
max_lifetime,
Some(Duration::from_secs(0)),
"max_lifetime must be positive"
);
self.max_lifetime = max_lifetime;
self
}
pub fn max_idle_lifetime(mut self, max_idle_lifetime: Option<Duration>) -> Self {
assert_ne!(
max_idle_lifetime,
Some(Duration::from_secs(0)),
"max_idle_lifetime must be positive"
);
self.max_idle_lifetime = max_idle_lifetime;
self
}
pub fn get_timeout(mut self, get_timeout: Option<Duration>) -> Self {
assert_ne!(
get_timeout,
Some(Duration::from_secs(0)),
"get_timeout must be positive"
);
self.get_timeout = get_timeout;
self
}
pub fn health_check_interval(mut self, health_check_interval: Option<Duration>) -> Self {
assert_ne!(
health_check_interval,
Some(Duration::from_secs(0)),
"health_check_interval must be positive"
);
self.health_check_interval = health_check_interval;
self
}
#[doc(hidden)]
#[allow(dead_code)]
pub fn clean_rate(mut self, clean_rate: Duration) -> Builder<M> {
assert!(
clean_rate > Duration::from_secs(0),
"connection_timeout must be positive"
);
if clean_rate > Duration::from_secs(1) {
self.clean_rate = clean_rate;
}
self
}
pub fn build(self, manager: M) -> Pool<M> {
use std::cmp;
let max_idle = self
.max_idle
.unwrap_or_else(|| cmp::min(self.max_open, DEFAULT_MAX_IDLE_CONNS));
assert!(
self.max_open >= max_idle,
"max_idle must be no larger than max_open"
);
let config = Config {
max_open: self.max_open,
max_idle,
max_lifetime: self.max_lifetime,
max_idle_lifetime: self.max_idle_lifetime,
get_timeout: self.get_timeout,
clean_rate: self.clean_rate,
max_bad_conn_retries: self.max_bad_conn_retries,
health_check: self.health_check,
health_check_interval: self.health_check_interval,
};
Pool::new_inner(manager, config)
}
}