From e74ff0da2812cb18910adcc46eb9f5ba7a057688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Saparelli?= Date: Mon, 29 Jun 2026 12:45:32 +1200 Subject: [PATCH] fix(db): add bounds to the pool --- crates/database/src/lib.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/crates/database/src/lib.rs b/crates/database/src/lib.rs index b4812f6b..a94f3f9e 100644 --- a/crates/database/src/lib.rs +++ b/crates/database/src/lib.rs @@ -1,3 +1,5 @@ +use std::time::Duration; + use diesel_async::{ AsyncPgConnection, pooled_connection::{AsyncDieselConnectionManager, mobc::Pool}, @@ -52,5 +54,25 @@ pub fn init() -> Db { } pub fn init_to(url: &str) -> Db { - Pool::new(AsyncDieselConnectionManager::::new(url)) + // Bound the pool. Every pod that links this crate (the two servers plus each + // job) runs its own pool against the same primary; mobc's defaults + // (max_open=10, idle and lifetimes uncapped) let the fleet's aggregate + // demand exceed the server's max_connections and pin backends indefinitely. + // Size per role via env, and recycle connections so a failover doesn't leave + // the pool holding dead backends. + let max_open = env_u64("DB_MAX_OPEN_CONNECTIONS", 5); + let max_idle = env_u64("DB_MAX_IDLE_CONNECTIONS", 2); + Pool::builder() + .max_open(max_open) + .max_idle(max_idle) + .max_lifetime(Some(Duration::from_secs(30 * 60))) + .max_idle_lifetime(Some(Duration::from_secs(10 * 60))) + .build(AsyncDieselConnectionManager::::new(url)) +} + +fn env_u64(key: &str, default: u64) -> u64 { + std::env::var(key) + .ok() + .and_then(|v| v.parse().ok()) + .unwrap_or(default) }