use super::DatabasePool;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering::Relaxed};
#[derive(Debug)]
pub struct ConnectionPool<P = DatabasePool> {
name: &'static str,
database: &'static str,
pool: P,
available: AtomicBool,
missed_count: AtomicUsize,
}
impl<P> ConnectionPool<P> {
#[inline]
pub fn new(name: &'static str, database: &'static str, pool: P) -> Self {
Self {
name,
database,
pool,
available: AtomicBool::new(true),
missed_count: AtomicUsize::new(0),
}
}
#[inline]
pub fn is_available(&self) -> bool {
self.available.load(Relaxed)
}
pub fn store_availability(&self, available: bool) {
self.available.store(available, Relaxed);
if available {
self.reset_missed_count();
} else {
self.increment_missed_count();
}
}
#[inline]
pub fn missed_count(&self) -> usize {
self.missed_count.load(Relaxed)
}
#[inline]
pub fn increment_missed_count(&self) {
self.missed_count.fetch_add(1, Relaxed);
}
#[inline]
pub fn reset_missed_count(&self) {
self.missed_count.store(0, Relaxed);
}
#[inline]
pub fn is_retryable(&self) -> bool {
let missed_count = self.missed_count();
missed_count > 2 && missed_count.is_power_of_two()
}
#[inline]
pub fn name(&self) -> &'static str {
self.name
}
#[inline]
pub fn database(&self) -> &'static str {
self.database
}
#[inline]
pub fn pool(&self) -> &P {
&self.pool
}
}