use std::sync::mpsc;
use crate::config::PoolConfig;
use crate::connection::ConnImpl;
use crate::error::Error;
use super::PoolContentsRef;
pub(super) struct PoolManager {
config: PoolConfig,
receive_channel: mpsc::Receiver<PoolManagerRequest>,
contents_ref: PoolContentsRef,
}
pub(super) enum PoolManagerRequest {
GrowPool,
ClosePool,
DropConnection(ConnImpl),
PingConnection(ConnImpl),
}
impl PoolManager {
fn grow_pool(&self) {
let result =
ConnImpl::connect(self.config.connection_config().clone());
self.contents_ref.lock().unwrap().add_new_connection(result);
}
fn ping_connection(&self, conn_impl: ConnImpl) -> Result<ConnImpl, Error> {
let orig_call_timeout = conn_impl.get_call_timeout()?;
conn_impl.ping()?;
conn_impl.set_call_timeout(orig_call_timeout)?;
Ok(conn_impl)
}
pub(super) fn new(
contents_ref: PoolContentsRef,
receive_channel: mpsc::Receiver<PoolManagerRequest>,
config: PoolConfig,
) -> PoolManager {
PoolManager {
config,
receive_channel,
contents_ref,
}
}
pub(super) fn run(&mut self) {
for request in &self.receive_channel {
match request {
PoolManagerRequest::GrowPool => {
self.grow_pool();
}
PoolManagerRequest::ClosePool => {
break;
}
PoolManagerRequest::DropConnection(mut conn_impl) => {
let _ = conn_impl.close();
}
PoolManagerRequest::PingConnection(conn_impl) => {
let result = self.ping_connection(conn_impl).ok();
self.contents_ref
.lock()
.unwrap()
.add_pinged_connection(result);
}
}
}
}
}