1use super::DatabasePool;
2use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering::Relaxed};
3
4#[derive(Debug)]
6pub struct ConnectionPool<P = DatabasePool> {
7 name: &'static str,
9 database: &'static str,
11 pool: P,
13 available: AtomicBool,
15 missed_count: AtomicUsize,
17}
18
19impl<P> ConnectionPool<P> {
20 #[inline]
22 pub fn new(name: &'static str, database: &'static str, pool: P) -> Self {
23 Self {
24 name,
25 database,
26 pool,
27 available: AtomicBool::new(true),
28 missed_count: AtomicUsize::new(0),
29 }
30 }
31
32 #[inline]
34 pub fn is_available(&self) -> bool {
35 self.available.load(Relaxed)
36 }
37
38 pub fn store_availability(&self, available: bool) {
40 self.available.store(available, Relaxed);
41 if available {
42 self.reset_missed_count();
43 } else {
44 self.increment_missed_count();
45 }
46 }
47
48 #[inline]
50 pub fn missed_count(&self) -> usize {
51 self.missed_count.load(Relaxed)
52 }
53
54 #[inline]
56 pub fn increment_missed_count(&self) {
57 self.missed_count.fetch_add(1, Relaxed);
58 }
59
60 #[inline]
62 pub fn reset_missed_count(&self) {
63 self.missed_count.store(0, Relaxed);
64 }
65
66 #[inline]
68 pub fn is_retryable(&self) -> bool {
69 let missed_count = self.missed_count();
70 missed_count > 2 && missed_count.is_power_of_two()
71 }
72
73 #[inline]
75 pub fn name(&self) -> &'static str {
76 self.name
77 }
78
79 #[inline]
81 pub fn database(&self) -> &'static str {
82 self.database
83 }
84
85 #[inline]
87 pub fn pool(&self) -> &P {
88 &self.pool
89 }
90}