Skip to content

Commit 23d2853

Browse files
committed
store: Reset store_connection_wait_time_ms after long inactivity
1 parent 0ff94bd commit 23d2853

File tree

2 files changed

+23
-7
lines changed

2 files changed

+23
-7
lines changed

store/postgres/src/pool/manager.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use std::sync::atomic::AtomicBool;
2323
use std::sync::atomic::Ordering;
2424
use std::sync::Arc;
2525
use std::sync::RwLock;
26-
use std::time::Duration;
26+
use std::time::{Duration, Instant};
2727

2828
use crate::pool::AsyncPool;
2929

@@ -241,8 +241,13 @@ pub(crate) fn spawn_size_stat_collector(
241241
/// Reap connections that are too old (older than 30 minutes) or if there
242242
/// are more than `connection_min_idle` connections in the pool that have
243243
/// been idle for longer than `idle_timeout`
244-
pub(crate) fn spawn_connection_reaper(pool: AsyncPool, idle_timeout: Duration) {
244+
pub(crate) fn spawn_connection_reaper(
245+
pool: AsyncPool,
246+
idle_timeout: Duration,
247+
wait_gauge: Option<Gauge>,
248+
) {
245249
const MAX_LIFETIME: Duration = Duration::from_secs(30 * 60);
250+
const CHECK_INTERVAL: Duration = Duration::from_secs(30);
246251
let Some(min_idle) = ENV_VARS.store.connection_min_idle else {
247252
// If this is None, we will never reap anything
248253
return;
@@ -254,7 +259,9 @@ pub(crate) fn spawn_connection_reaper(pool: AsyncPool, idle_timeout: Duration) {
254259
tokio::task::spawn(async move {
255260
loop {
256261
let mut idle_count = 0;
262+
let mut last_used = Instant::now();
257263
pool.retain(|_, metrics| {
264+
last_used = last_used.min(metrics.recycled.unwrap_or(metrics.created));
258265
if metrics.age() > MAX_LIFETIME {
259266
return false;
260267
}
@@ -264,13 +271,18 @@ pub(crate) fn spawn_connection_reaper(pool: AsyncPool, idle_timeout: Duration) {
264271
}
265272
true
266273
});
267-
tokio::time::sleep(Duration::from_secs(30)).await;
274+
if last_used.elapsed() > CHECK_INTERVAL {
275+
// Reset wait time if there was no activity recently so that
276+
// we don't report stale wait times
277+
wait_gauge.as_ref().map(|wait_gauge| wait_gauge.set(0.0));
278+
}
279+
tokio::time::sleep(CHECK_INTERVAL).await;
268280
}
269281
});
270282
}
271283

272284
pub(crate) struct WaitMeter {
273-
wait_gauge: Gauge,
285+
pub(crate) wait_gauge: Gauge,
274286
pub(crate) wait_stats: PoolWaitStats,
275287
}
276288

store/postgres/src/pool/mod.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -497,10 +497,14 @@ impl PoolInner {
497497

498498
manager::spawn_size_stat_collector(pool.clone(), &registry, const_labels.clone());
499499

500-
manager::spawn_connection_reaper(pool.clone(), ENV_VARS.store.connection_idle_timeout);
501-
502500
let wait_meter = WaitMeter::new(&registry, const_labels.clone());
503501

502+
manager::spawn_connection_reaper(
503+
pool.clone(),
504+
ENV_VARS.store.connection_idle_timeout,
505+
Some(wait_meter.wait_gauge.clone()),
506+
);
507+
504508
let fdw_pool = fdw_pool_size.map(|pool_size| {
505509
let fdw_timeouts = Timeouts {
506510
wait: Some(ENV_VARS.store.connection_timeout),
@@ -517,7 +521,7 @@ impl PoolInner {
517521
.build()
518522
.expect("failed to create fdw connection pool");
519523

520-
manager::spawn_connection_reaper(fdw_pool.clone(), FDW_IDLE_TIMEOUT);
524+
manager::spawn_connection_reaper(fdw_pool.clone(), FDW_IDLE_TIMEOUT, None);
521525
fdw_pool
522526
});
523527

0 commit comments

Comments
 (0)