From 9fcc5299c3ce020d0d0b9ae41d112436b786d083 Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Mon, 14 Apr 2025 17:36:07 +1000 Subject: [PATCH] Improve db_pools init: do not crash if DB unavailable during startup ## Why? When using `Pool::connect[_with]`, sqlx attempts to connect to the given database immediately, and the fairing will fail if there are any problems in that attempt (beyond obvious configuration problems that are found before hitting the network), e.g.: - the database is unavailable; or - the username/password is incorrect; or - the ssl configuration is invalid; or - any other connection issue. There are a few pros and cons to this approach: Pros: - In development, configuration errors are surfaced slightly faster Cons: - Databases are expected to be unavailable sometimes. It does not normally crash a server if one becomes unavailable after startup, so why should it prevent a server from starting at all? See [deadpool's justification]{https://docs.rs/deadpool} for not crashing. - In production/testing, slower to debug configuration or networking errors as your edit-test loop now involves restarting an application rather than refreshing a page or trying a request again. - Causes database or configuration issues to appear as "failed deployments" in standard deployment scenarios. - Introduces hard ordering constraints on operator actions during database recovery, requiring reboots to follow a functioning database or applications not to be restarted at certain times ## Effect of change The sqlx backend now behaves like the deadpool backend: no connection issues are surfaced during startup. You will not see them until you attempt to get a connection from the pool. That means rocket will launch and you can find problems like these in smoke tests. --- contrib/db_pools/lib/src/pool.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/contrib/db_pools/lib/src/pool.rs b/contrib/db_pools/lib/src/pool.rs index b37fecced4..3d54dc485d 100644 --- a/contrib/db_pools/lib/src/pool.rs +++ b/contrib/db_pools/lib/src/pool.rs @@ -276,14 +276,12 @@ mod sqlx { } } - sqlx::pool::PoolOptions::new() + Ok(sqlx::pool::PoolOptions::new() .max_connections(config.max_connections as u32) .acquire_timeout(Duration::from_secs(config.connect_timeout)) .idle_timeout(config.idle_timeout.map(Duration::from_secs)) .min_connections(config.min_connections.unwrap_or_default()) - .connect_with(opts) - .await - .map_err(Error::Init) + .connect_lazy_with(opts)) } async fn get(&self) -> Result {