|
| 1 | +//! Log the current state of the database connection pool at most once per minute |
| 2 | +
|
| 3 | +use super::prelude::*; |
| 4 | +use crate::app::App; |
| 5 | + |
| 6 | +use conduit::Request; |
| 7 | +use std::sync::{ |
| 8 | + atomic::{AtomicUsize, Ordering}, |
| 9 | + Arc, Mutex, |
| 10 | +}; |
| 11 | +use std::time::{Duration, Instant}; |
| 12 | + |
| 13 | +#[derive(Clone)] |
| 14 | +pub(crate) struct LogConnectionPoolStatus { |
| 15 | + app: Arc<App>, |
| 16 | + last_log_time: Arc<Mutex<Instant>>, |
| 17 | + in_flight_requests: Arc<AtomicUsize>, |
| 18 | +} |
| 19 | + |
| 20 | +impl LogConnectionPoolStatus { |
| 21 | + pub(crate) fn new(app: &Arc<App>) -> Self { |
| 22 | + Self { |
| 23 | + app: app.clone(), |
| 24 | + last_log_time: Arc::new(Mutex::new(Instant::now())), |
| 25 | + in_flight_requests: Arc::new(AtomicUsize::new(0)), |
| 26 | + } |
| 27 | + } |
| 28 | +} |
| 29 | + |
| 30 | +impl Middleware for LogConnectionPoolStatus { |
| 31 | + fn before(&self, _: &mut dyn Request) -> Result<(), Box<dyn Error + Send>> { |
| 32 | + let mut last_log_time = self.last_log_time.lock().unwrap_or_else(|e| e.into_inner()); |
| 33 | + let in_flight_requests = self.in_flight_requests.fetch_add(1, Ordering::SeqCst); |
| 34 | + if last_log_time.elapsed() >= Duration::from_secs(60) { |
| 35 | + *last_log_time = Instant::now(); |
| 36 | + println!( |
| 37 | + "connection_pool_status=\"{:?}\" in_flight_requests={}", |
| 38 | + self.app.diesel_database.state(), |
| 39 | + in_flight_requests |
| 40 | + ); |
| 41 | + } |
| 42 | + Ok(()) |
| 43 | + } |
| 44 | + |
| 45 | + fn after( |
| 46 | + &self, |
| 47 | + _: &mut dyn Request, |
| 48 | + res: Result<Response, Box<dyn Error + Send>>, |
| 49 | + ) -> Result<Response, Box<dyn Error + Send>> { |
| 50 | + self.in_flight_requests.fetch_sub(1, Ordering::SeqCst); |
| 51 | + res |
| 52 | + } |
| 53 | +} |
0 commit comments