Skip to content

Commit d2e6e13

Browse files
cursoragentlovasoa
andcommitted
Refactor timeout resolution to AppConfig
Co-authored-by: contact <contact@ophir.dev>
1 parent fc94be6 commit d2e6e13

2 files changed

Lines changed: 48 additions & 28 deletions

File tree

src/app_config.rs

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use serde::de::Error;
99
use serde::{Deserialize, Deserializer, Serialize};
1010
use std::net::{SocketAddr, ToSocketAddrs};
1111
use std::path::{Path, PathBuf};
12+
use std::time::Duration;
1213

1314
#[cfg(not(feature = "lambda-web"))]
1415
const DEFAULT_DATABASE_FILE: &str = "sqlpage.db";
@@ -73,6 +74,8 @@ impl AppConfig {
7374
.validate()
7475
.context("The provided configuration is invalid")?;
7576

77+
config.resolve_timeouts();
78+
7679
log::debug!("Loaded configuration: {config:#?}");
7780
log::info!(
7881
"Configuration loaded from {}",
@@ -82,6 +85,26 @@ impl AppConfig {
8285
Ok(config)
8386
}
8487

88+
fn resolve_timeouts(&mut self) {
89+
let is_sqlite = self.database_url.starts_with("sqlite:");
90+
self.database_connection_idle_timeout = resolve_timeout(
91+
self.database_connection_idle_timeout_seconds_raw,
92+
if is_sqlite {
93+
None
94+
} else {
95+
Some(Duration::from_secs(30 * 60))
96+
},
97+
);
98+
self.database_connection_max_lifetime = resolve_timeout(
99+
self.database_connection_max_lifetime_seconds_raw,
100+
if is_sqlite {
101+
None
102+
} else {
103+
Some(Duration::from_secs(60 * 60))
104+
},
105+
);
106+
}
107+
85108
fn validate(&self) -> anyhow::Result<()> {
86109
if !self.web_root.is_dir() {
87110
return Err(anyhow::anyhow!(
@@ -107,12 +130,12 @@ impl AppConfig {
107130
));
108131
}
109132
}
110-
if let Some(idle_timeout) = self.database_connection_idle_timeout_seconds {
133+
if let Some(idle_timeout) = self.database_connection_idle_timeout_seconds_raw {
111134
if idle_timeout < 0.0 {
112135
log::warn!("Database connection idle timeout is negative, this will disable the timeout");
113136
}
114137
}
115-
if let Some(max_lifetime) = self.database_connection_max_lifetime_seconds {
138+
if let Some(max_lifetime) = self.database_connection_max_lifetime_seconds_raw {
116139
if max_lifetime < 0.0 {
117140
log::warn!("Database connection max lifetime is negative, this will disable the timeout");
118141
}
@@ -142,8 +165,15 @@ pub struct AppConfig {
142165
#[serde(default)]
143166
pub database_password: Option<String>,
144167
pub max_database_pool_connections: Option<u32>,
145-
pub database_connection_idle_timeout_seconds: Option<f64>,
146-
pub database_connection_max_lifetime_seconds: Option<f64>,
168+
#[serde(rename = "database_connection_idle_timeout_seconds")]
169+
pub database_connection_idle_timeout_seconds_raw: Option<f64>,
170+
#[serde(rename = "database_connection_max_lifetime_seconds")]
171+
pub database_connection_max_lifetime_seconds_raw: Option<f64>,
172+
173+
#[serde(skip)]
174+
pub database_connection_idle_timeout: Option<Duration>,
175+
#[serde(skip)]
176+
pub database_connection_max_lifetime: Option<Duration>,
147177

148178
#[serde(default)]
149179
pub sqlite_extensions: Vec<String>,
@@ -607,6 +637,14 @@ impl DevOrProd {
607637
}
608638
}
609639

640+
fn resolve_timeout(config_val: Option<f64>, default: Option<Duration>) -> Option<Duration> {
641+
match config_val {
642+
Some(v) if v <= 0.0 || !v.is_finite() => None,
643+
Some(v) => Some(Duration::from_secs_f64(v)),
644+
None => default,
645+
}
646+
}
647+
610648
#[must_use]
611649
pub fn test_database_url() -> String {
612650
std::env::var("DATABASE_URL").unwrap_or_else(|_| "sqlite::memory:".to_string())
@@ -619,14 +657,16 @@ pub mod tests {
619657

620658
#[must_use]
621659
pub fn test_config() -> AppConfig {
622-
serde_json::from_str::<AppConfig>(
660+
let mut config = serde_json::from_str::<AppConfig>(
623661
&serde_json::json!({
624662
"database_url": test_database_url(),
625663
"listen_on": "localhost:8080"
626664
})
627665
.to_string(),
628666
)
629-
.unwrap()
667+
.unwrap();
668+
config.resolve_timeouts();
669+
config
630670
}
631671
}
632672

src/webserver/database/connect.rs

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -89,20 +89,8 @@ impl Database {
8989
AnyKind::Mssql => 100,
9090
}
9191
})
92-
.idle_timeout(resolve_timeout(
93-
config.database_connection_idle_timeout_seconds,
94-
match kind {
95-
AnyKind::Sqlite => None,
96-
_ => Some(Duration::from_secs(30 * 60)),
97-
},
98-
))
99-
.max_lifetime(resolve_timeout(
100-
config.database_connection_max_lifetime_seconds,
101-
match kind {
102-
AnyKind::Sqlite => None,
103-
_ => Some(Duration::from_secs(60 * 60)),
104-
},
105-
))
92+
.idle_timeout(config.database_connection_idle_timeout)
93+
.max_lifetime(config.database_connection_max_lifetime)
10694
.acquire_timeout(Duration::from_secs_f64(
10795
config.database_connection_acquire_timeout_seconds,
10896
));
@@ -262,11 +250,3 @@ fn set_database_password(options: &mut AnyConnectOptions, password: &str) {
262250
unreachable!("Unsupported database type");
263251
}
264252
}
265-
266-
fn resolve_timeout(config_val: Option<f64>, default: Option<Duration>) -> Option<Duration> {
267-
match config_val {
268-
Some(v) if v <= 0.0 || !v.is_finite() => None,
269-
Some(v) => Some(Duration::from_secs_f64(v)),
270-
None => default,
271-
}
272-
}

0 commit comments

Comments
 (0)