use libsql::Connection;
use parking_lot::RwLock;
use std::mem::ManuallyDrop;
use std::sync::Arc;
use std::time::Instant;
use super::PooledConnection;
use super::config::KeepAliveStatistics;
#[derive(Debug)]
pub struct KeepAliveConnection {
pooled: ManuallyDrop<PooledConnection>,
connection_id: usize,
last_used: RwLock<Instant>,
stats: Arc<RwLock<KeepAliveStatistics>>,
}
impl KeepAliveConnection {
pub fn new(
pooled: PooledConnection,
connection_id: usize,
last_used: Instant,
stats: Arc<RwLock<KeepAliveStatistics>>,
) -> Self {
Self {
pooled: ManuallyDrop::new(pooled),
connection_id,
last_used: RwLock::new(last_used),
stats,
}
}
pub fn connection(&self) -> do_memory_core::Result<&Connection> {
self.pooled.connection().ok_or_else(|| {
do_memory_core::Error::Storage(
"KeepAliveConnection: underlying connection is None".to_string(),
)
})
}
pub fn connection_id(&self) -> usize {
self.connection_id
}
pub fn last_used(&self) -> Instant {
*self.last_used.read()
}
pub fn update_last_used(&self) {
let mut last_used = self.last_used.write();
*last_used = Instant::now();
}
pub fn into_connection(mut self) -> do_memory_core::Result<Connection> {
let pooled = unsafe { ManuallyDrop::take(&mut self.pooled) };
pooled.into_inner()
}
}
impl Drop for KeepAliveConnection {
fn drop(&mut self) {
unsafe {
ManuallyDrop::drop(&mut self.pooled);
}
let mut stats = self.stats.write();
if stats.active_connections > 0 {
stats.active_connections -= 1;
}
}
}