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 auto_migration: AtomicBool,
19}
20
21impl<P> ConnectionPool<P> {
22 #[inline]
24 pub fn new(name: &'static str, database: &'static str, pool: P) -> Self {
25 Self {
26 name,
27 database,
28 pool,
29 available: AtomicBool::new(true),
30 missed_count: AtomicUsize::new(0),
31 auto_migration: AtomicBool::new(true),
32 }
33 }
34
35 #[inline]
37 pub fn is_available(&self) -> bool {
38 self.available.load(Relaxed)
39 }
40
41 #[inline]
43 pub fn store_availability(&self, available: bool) {
44 self.available.store(available, Relaxed);
45 if available {
46 self.reset_missed_count();
47 } else {
48 self.increment_missed_count();
49 }
50 }
51
52 #[inline]
54 pub fn disable_auto_migration(&self) {
55 self.auto_migration.store(false, Relaxed);
56 }
57
58 #[inline]
60 pub fn missed_count(&self) -> usize {
61 self.missed_count.load(Relaxed)
62 }
63
64 #[inline]
66 pub fn increment_missed_count(&self) {
67 self.missed_count.fetch_add(1, Relaxed);
68 }
69
70 #[inline]
72 pub fn reset_missed_count(&self) {
73 self.missed_count.store(0, Relaxed);
74 }
75
76 #[inline]
78 pub fn is_retryable(&self) -> bool {
79 let missed_count = self.missed_count();
80 missed_count > 2 && missed_count.is_power_of_two()
81 }
82
83 #[inline]
85 pub fn auto_migration(&self) -> bool {
86 self.auto_migration.load(Relaxed)
87 }
88
89 #[inline]
91 pub fn name(&self) -> &'static str {
92 self.name
93 }
94
95 #[inline]
97 pub fn database(&self) -> &'static str {
98 self.database
99 }
100
101 #[inline]
103 pub fn pool(&self) -> &P {
104 &self.pool
105 }
106}