mirror of
https://github.com/goauthentik/authentik.git
synced 2026-06-17 19:09:11 +03:00
packages/ak-common/db: fix conn_max_age causing spinning (#22679)
* packages/ak-common/config: fix option int parsing, specifically for conn_max_age Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space> * packages/ak-common/db: fix conn_max_age usage Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space> --------- Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
This commit is contained in:
committed by
GitHub
parent
ed5b7d17b1
commit
5c1eb0e449
@@ -276,7 +276,7 @@ class ConfigLoader:
|
||||
try:
|
||||
return int(value)
|
||||
except (ValueError, TypeError) as exc:
|
||||
if value is None or (isinstance(value, str) and value.lower() == "null"):
|
||||
if value is None or (isinstance(value, str) and value.lower() in ("", "null", "none")):
|
||||
return None
|
||||
self.log("warning", "Failed to parse config as int", path=path, exc=str(exc))
|
||||
return default
|
||||
|
||||
@@ -22,6 +22,7 @@ postgresql:
|
||||
port: 5432
|
||||
password: "env://POSTGRES_PASSWORD"
|
||||
sslmode: disable
|
||||
conn_max_age: 0
|
||||
conn_health_checks: false
|
||||
use_pool: False
|
||||
test:
|
||||
|
||||
@@ -315,7 +315,7 @@ class TestConfig(TestCase):
|
||||
{
|
||||
"default": {
|
||||
"DISABLE_SERVER_SIDE_CURSORS": True,
|
||||
"CONN_MAX_AGE": None,
|
||||
"CONN_MAX_AGE": 0,
|
||||
"CONN_HEALTH_CHECKS": False,
|
||||
"ENGINE": "psqlextra.backend",
|
||||
"HOST": "foo",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::{collections::HashMap, net::SocketAddr, num::NonZeroUsize};
|
||||
|
||||
use ipnet::IpNet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Deserializer, Serialize, de::Error as _};
|
||||
|
||||
pub(super) const KEYS_TO_PARSE_AS_LIST: [&str; 4] = [
|
||||
"listen.http",
|
||||
@@ -10,6 +10,32 @@ pub(super) const KEYS_TO_PARSE_AS_LIST: [&str; 4] = [
|
||||
"log.http_headers",
|
||||
];
|
||||
|
||||
fn deserialize_optional_u64<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
// The value comes as a number from config files but as a string from env vars.
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum NumOrStr {
|
||||
Num(u64),
|
||||
Str(String),
|
||||
}
|
||||
|
||||
match Option::<NumOrStr>::deserialize(deserializer)? {
|
||||
None => Ok(None),
|
||||
Some(NumOrStr::Num(n)) => Ok(Some(n)),
|
||||
Some(NumOrStr::Str(s)) => {
|
||||
let s = s.trim();
|
||||
if s.is_empty() || s.eq_ignore_ascii_case("none") || s.eq_ignore_ascii_case("null") {
|
||||
Ok(None)
|
||||
} else {
|
||||
s.parse().map(Some).map_err(D::Error::custom)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Config {
|
||||
pub postgresql: PostgreSQLConfig,
|
||||
@@ -50,6 +76,7 @@ pub struct PostgreSQLConfig {
|
||||
pub sslcert: Option<String>,
|
||||
pub sslkey: Option<String>,
|
||||
|
||||
#[serde(deserialize_with = "deserialize_optional_u64")]
|
||||
pub conn_max_age: Option<u64>,
|
||||
pub conn_health_checks: bool,
|
||||
|
||||
|
||||
@@ -68,7 +68,6 @@ pub async fn init(tasks: &mut Tasks) -> Result<()> {
|
||||
.min_connections(1)
|
||||
.max_connections(4)
|
||||
.acquire_time_level(LevelFilter::Trace)
|
||||
.max_lifetime(config.postgresql.conn_max_age.map(Duration::from_secs))
|
||||
.test_before_acquire(config.postgresql.conn_health_checks)
|
||||
.after_connect(|conn, _meta| {
|
||||
Box::pin(async move {
|
||||
@@ -84,6 +83,11 @@ pub async fn init(tasks: &mut Tasks) -> Result<()> {
|
||||
})
|
||||
});
|
||||
|
||||
let pool_options = match config.postgresql.conn_max_age {
|
||||
Some(0) => pool_options.after_release(|_conn, _meta| Box::pin(async { Ok(false) })),
|
||||
other => pool_options.max_lifetime(other.map(Duration::from_secs)),
|
||||
};
|
||||
|
||||
let pool = pool_options.connect_with(options).await?;
|
||||
DB.get_or_init(|| pool);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user