use super::metrics::Histogram;
use crate::db::conn::PConn;
use crate::error::DatabaseResult;
use rusqlite::Transaction;
use std::ops::{Deref, DerefMut};
use std::time::Instant;
use tokio::sync::OwnedSemaphorePermit;
pub(super) struct PConnGuard {
conn: PConn,
created: Instant,
use_time_metric: Histogram,
_permit: OwnedSemaphorePermit,
}
impl PConnGuard {
pub(super) fn new(
conn: PConn,
permit: OwnedSemaphorePermit,
use_time_metric: Histogram,
) -> Self {
PConnGuard {
conn,
created: Instant::now(),
use_time_metric,
_permit: permit,
}
}
}
impl Deref for PConnGuard {
type Target = PConn;
fn deref(&self) -> &Self::Target {
&self.conn
}
}
impl DerefMut for PConnGuard {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.conn
}
}
impl Drop for PConnGuard {
fn drop(&mut self) {
self.use_time_metric
.record(self.created.elapsed().as_secs_f64(), &[]);
}
}
pub struct PTxnGuard(PConnGuard, Instant);
impl PTxnGuard {
pub fn transaction(&mut self) -> DatabaseResult<Transaction<'_>> {
Ok(self.0.transaction()?)
}
}
impl From<PConnGuard> for PTxnGuard {
fn from(value: PConnGuard) -> Self {
PTxnGuard(value, Instant::now())
}
}
impl Drop for PTxnGuard {
fn drop(&mut self) {
let elapsed_millis = self.1.elapsed().as_millis();
if elapsed_millis > 50 {
tracing::debug!("PTxnGuard was held for {:?}ms", elapsed_millis);
}
}
}