use std::{sync::Weak, time::Duration};
use super::{ConnectionPool, ConnectionPoolInner};
use crate::{event::cmap::ConnectionClosedReason, RUNTIME};
pub(crate) fn start_background_task(pool: Weak<ConnectionPoolInner>) {
RUNTIME.execute(async move {
loop {
match pool.upgrade() {
Some(pool) => perform_checks(pool.into()).await,
None => return,
};
RUNTIME.delay_for(Duration::from_millis(10)).await;
}
});
}
async fn perform_checks(pool: ConnectionPool) {
pool.remove_perished_connections().await;
pool.ensure_min_connections().await;
}
impl ConnectionPool {
async fn remove_perished_connections(&self) {
let mut connection_manager = self.inner.connection_manager.lock().await;
let mut i = 0;
while i < connection_manager.checked_in_connections.len() {
if connection_manager.checked_in_connections[i].is_stale(connection_manager.generation)
{
let connection = connection_manager.checked_in_connections.remove(i);
connection_manager.close_connection(connection, ConnectionClosedReason::Stale);
} else if connection_manager.checked_in_connections[i].is_idle(self.inner.max_idle_time)
{
let connection = connection_manager.checked_in_connections.remove(i);
connection_manager.close_connection(connection, ConnectionClosedReason::Idle);
} else {
i += 1;
}
}
}
async fn ensure_min_connections(&self) {
if let Some(min_pool_size) = self.inner.min_pool_size {
loop {
let mut connection_manager = self.inner.connection_manager.lock().await;
if connection_manager.total_connection_count < min_pool_size {
match connection_manager.create_connection().await {
Ok(connection) => {
connection_manager.checked_in_connections.push(connection)
}
Err(_) => {
return;
}
}
} else {
return;
}
}
}
}
}