From 9f89588c972c9667578a805ebc2139548efc2f35 Mon Sep 17 00:00:00 2001 From: Pau Freixes Date: Fri, 31 May 2024 17:22:52 +0200 Subject: [PATCH] Try to merge State with Statistics --- bb8/src/api.rs | 20 ++++++++++++++------ bb8/src/inner.rs | 35 ++++------------------------------- bb8/src/internals.rs | 13 ++++++++++++- bb8/tests/test.rs | 4 ++-- 4 files changed, 32 insertions(+), 40 deletions(-) diff --git a/bb8/src/api.rs b/bb8/src/api.rs index 30f3725..004790d 100644 --- a/bb8/src/api.rs +++ b/bb8/src/api.rs @@ -8,7 +8,6 @@ use std::time::Duration; use async_trait::async_trait; use crate::inner::PoolInner; -pub use crate::inner::Statistics; use crate::internals::Conn; /// A generic connection pool. @@ -45,11 +44,6 @@ impl Pool { Builder::new() } - /// Returns statistics about the historical usage of the pool. - pub fn statistics(&self) -> Statistics { - self.inner.statistics() - } - /// Retrieves a connection from the pool. pub async fn get(&self) -> Result, RunError> { self.inner.get().await @@ -91,6 +85,20 @@ pub struct State { pub connections: u32, /// The number of idle connections. pub idle_connections: u32, + /// Statistics about the historical usage of the pool. + pub statistics: Statistics, +} + +/// Statistics about the historical usage of the `Pool`. +#[derive(Debug, Default)] +#[non_exhaustive] +pub struct Statistics { + /// Total gets performed that did not have to wait for a connection. + pub get_direct: u64, + /// Total gets performed that had to wait for a connection available. + pub get_waited: u64, + /// Total gets performed that timed out while waiting for a connection. + pub get_timed_out: u64, } /// A builder for a connection pool. diff --git a/bb8/src/inner.rs b/bb8/src/inner.rs index 6bbf69a..3f250d5 100644 --- a/bb8/src/inner.rs +++ b/bb8/src/inner.rs @@ -1,7 +1,6 @@ use std::cmp::{max, min}; use std::fmt; use std::future::Future; -use std::sync::atomic::Ordering; use std::sync::{Arc, Weak}; use std::time::{Duration, Instant}; @@ -11,7 +10,7 @@ use tokio::spawn; use tokio::time::{interval_at, sleep, timeout, Interval}; use crate::api::{Builder, ConnectionState, ManageConnection, PooledConnection, RunError, State}; -use crate::internals::{Approval, ApprovalIter, AtomicStatistics, Conn, GetKind, SharedPool}; +use crate::internals::{Approval, ApprovalIter, Conn, GetKind, SharedPool}; pub(crate) struct PoolInner where @@ -157,14 +156,11 @@ where } } - /// Returns statistics about the historical usage of the pool. - pub(crate) fn statistics(&self) -> Statistics { - (&(self.inner.statistics)).into() - } - /// Returns information about the current state of the pool. pub(crate) fn state(&self) -> State { - (&*self.inner.internals.lock()).into() + let mut state: State = (&*self.inner.internals.lock()).into(); + state.statistics = (&(self.inner.statistics)).into(); + state } // Outside of Pool to avoid borrow splitting issues on self @@ -260,26 +256,3 @@ impl Reaper { } } } - -/// Statistics about the historical usage of the `Pool`. -#[derive(Debug)] -#[non_exhaustive] -pub struct Statistics { - /// Information about gets. - /// Total gets performed that did not have to wait for a connection. - pub get_direct: u64, - /// Total gets performed that had to wait for a connection available. - pub get_waited: u64, - /// Total gets performed that timed out while waiting for a connection. - pub get_timed_out: u64, -} - -impl From<&AtomicStatistics> for Statistics { - fn from(item: &AtomicStatistics) -> Self { - Statistics { - get_direct: item.get_direct.load(Ordering::SeqCst), - get_waited: item.get_waited.load(Ordering::SeqCst), - get_timed_out: item.get_timed_out.load(Ordering::SeqCst), - } - } -} diff --git a/bb8/src/internals.rs b/bb8/src/internals.rs index 1ae45b0..dbfce90 100644 --- a/bb8/src/internals.rs +++ b/bb8/src/internals.rs @@ -6,7 +6,7 @@ use std::time::Instant; use crate::{api::QueueStrategy, lock::Mutex}; use tokio::sync::Notify; -use crate::api::{Builder, ManageConnection, State}; +use crate::api::{Builder, ManageConnection, State, Statistics}; use std::collections::VecDeque; /// The guts of a `Pool`. @@ -164,6 +164,7 @@ impl Into for &PoolInternals { State { connections: self.num_conns, idle_connections: self.conns.len() as u32, + statistics: Statistics::default(), } } } @@ -265,6 +266,16 @@ pub(crate) struct AtomicStatistics { pub(crate) get_timed_out: AtomicU64, } +impl From<&AtomicStatistics> for Statistics { + fn from(item: &AtomicStatistics) -> Self { + Statistics { + get_direct: item.get_direct.load(Ordering::SeqCst), + get_waited: item.get_waited.load(Ordering::SeqCst), + get_timed_out: item.get_timed_out.load(Ordering::SeqCst), + } + } +} + impl AtomicStatistics { pub(crate) fn record_get(&self, get_kind: GetKind) { match get_kind { diff --git a/bb8/tests/test.rs b/bb8/tests/test.rs index 661144c..ab3d8c8 100644 --- a/bb8/tests/test.rs +++ b/bb8/tests/test.rs @@ -315,7 +315,7 @@ async fn test_get_timeout() { ready(r).await.unwrap(); // check that the timed out was tracked - let statistics = pool.statistics(); + let statistics = pool.state().statistics; assert_eq!(statistics.get_timed_out, 1); } @@ -925,7 +925,7 @@ async fn test_statistics_get_waited() { // Wait for the second attempt to get a connection. f.await.unwrap(); - let statistics = pool.statistics(); + let statistics = pool.state().statistics; assert_eq!(statistics.get_direct, 1); assert_eq!(statistics.get_waited, 1); }