|
1 | 1 | use std::cmp::min;
|
| 2 | +use std::collections::VecDeque; |
| 3 | +use std::sync::atomic::{AtomicU64, Ordering}; |
2 | 4 | use std::sync::Arc;
|
3 | 5 | use std::time::Instant;
|
4 | 6 |
|
5 |
| -use crate::{api::QueueStrategy, lock::Mutex}; |
6 | 7 | use tokio::sync::Notify;
|
7 | 8 |
|
8 |
| -use crate::api::{Builder, ManageConnection, State}; |
9 |
| -use std::collections::VecDeque; |
| 9 | +use crate::api::{Builder, ManageConnection, QueueStrategy, State, Statistics}; |
| 10 | +use crate::lock::Mutex; |
10 | 11 |
|
11 | 12 | /// The guts of a `Pool`.
|
12 | 13 | #[allow(missing_debug_implementations)]
|
|
18 | 19 | pub(crate) manager: M,
|
19 | 20 | pub(crate) internals: Mutex<PoolInternals<M>>,
|
20 | 21 | pub(crate) notify: Arc<Notify>,
|
| 22 | + pub(crate) statistics: AtomicStatistics, |
21 | 23 | }
|
22 | 24 |
|
23 | 25 | impl<M> SharedPool<M>
|
|
30 | 32 | manager,
|
31 | 33 | internals: Mutex::new(PoolInternals::default()),
|
32 | 34 | notify: Arc::new(Notify::new()),
|
| 35 | + statistics: AtomicStatistics::default(), |
33 | 36 | }
|
34 | 37 | }
|
35 | 38 |
|
@@ -153,14 +156,12 @@ where
|
153 | 156 |
|
154 | 157 | self.dropped((before - self.conns.len()) as u32, config)
|
155 | 158 | }
|
156 |
| -} |
157 | 159 |
|
158 |
| -#[allow(clippy::from_over_into)] // Keep this more private with the internal type |
159 |
| -impl<M: ManageConnection> Into<State> for &PoolInternals<M> { |
160 |
| - fn into(self) -> State { |
| 160 | + pub(crate) fn state(&self, statistics: Statistics) -> State { |
161 | 161 | State {
|
162 | 162 | connections: self.num_conns,
|
163 | 163 | idle_connections: self.conns.len() as u32,
|
| 164 | + statistics, |
164 | 165 | }
|
165 | 166 | }
|
166 | 167 | }
|
@@ -248,3 +249,36 @@ impl<C: Send> From<Conn<C>> for IdleConn<C> {
|
248 | 249 | }
|
249 | 250 | }
|
250 | 251 | }
|
| 252 | + |
| 253 | +#[derive(Default)] |
| 254 | +pub(crate) struct AtomicStatistics { |
| 255 | + pub(crate) get_direct: AtomicU64, |
| 256 | + pub(crate) get_waited: AtomicU64, |
| 257 | + pub(crate) get_timed_out: AtomicU64, |
| 258 | +} |
| 259 | + |
| 260 | +impl AtomicStatistics { |
| 261 | + pub(crate) fn record(&self, kind: StatsKind) { |
| 262 | + match kind { |
| 263 | + StatsKind::Direct => self.get_direct.fetch_add(1, Ordering::SeqCst), |
| 264 | + StatsKind::Waited => self.get_waited.fetch_add(1, Ordering::SeqCst), |
| 265 | + StatsKind::TimedOut => self.get_timed_out.fetch_add(1, Ordering::SeqCst), |
| 266 | + }; |
| 267 | + } |
| 268 | +} |
| 269 | + |
| 270 | +impl From<&AtomicStatistics> for Statistics { |
| 271 | + fn from(item: &AtomicStatistics) -> Self { |
| 272 | + Self { |
| 273 | + get_direct: item.get_direct.load(Ordering::SeqCst), |
| 274 | + get_waited: item.get_waited.load(Ordering::SeqCst), |
| 275 | + get_timed_out: item.get_timed_out.load(Ordering::SeqCst), |
| 276 | + } |
| 277 | + } |
| 278 | +} |
| 279 | + |
| 280 | +pub(crate) enum StatsKind { |
| 281 | + Direct, |
| 282 | + Waited, |
| 283 | + TimedOut, |
| 284 | +} |
0 commit comments