use std::ops::{Deref, DerefMut};
use crate::manage_connection::ManageConnection;
use crate::queue::Live;
use crate::Pool;
pub struct Conn<C>
where
C: ManageConnection,
C::Connection: Send,
{
pub conn: Option<Live<C::Connection>>,
pub pool: Option<Pool<C>>,
should_be_put_back: bool,
}
impl<C> Conn<C>
where
C: ManageConnection,
C::Connection: Send,
{
pub(crate) fn new(connection: Live<C::Connection>, pool: Pool<C>) -> Self {
Self {
conn: Some(connection),
pool: Some(pool),
should_be_put_back: true,
}
}
pub(crate) fn forget(mut self) {
self.should_be_put_back = false;
drop(self);
}
}
impl<C> Deref for Conn<C>
where
C: ManageConnection,
C::Connection: Send,
{
type Target = C::Connection;
fn deref(&self) -> &Self::Target {
&self.conn.as_ref().unwrap().conn
}
}
impl<C> DerefMut for Conn<C>
where
C: ManageConnection,
C::Connection: Send,
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.conn.as_mut().unwrap().conn
}
}
impl<C> Drop for Conn<C>
where
C: ManageConnection,
C::Connection: Send,
{
fn drop(&mut self) {
if !self.should_be_put_back {
return;
}
let conn = self.conn.take().unwrap();
let pool = self.pool.take().unwrap();
pool.put_back(conn);
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::tests::DummyManager;
use crate::Config;
use std::time::Duration;
use tokio::time::sleep;
#[tokio::test]
async fn conn_pushes_back_into_pool_after_drop() {
let mngr = DummyManager::new();
let config = Config::new().min_size(2).max_size(2);
let pool = Pool::new(mngr, config).await.unwrap();
assert_eq!(pool.idle_conns(), 2);
let conn = pool.connection().await.unwrap();
assert_eq!(pool.idle_conns(), 1);
::std::mem::drop(conn);
sleep(Duration::from_secs(1)).await;
assert_eq!(pool.idle_conns(), 2);
}
}