Implement DynamicConfig with ArcSwap hot-reload and ConfigReloadHandle

Add ConfigReloadHandle with Arc<ArcSwap<DynamicConfig>> for lock-free reads
on the request hot path and tokio::sync::Mutex-serialized reload. Add static
config change detection via diff_static_config(). Add DynamicConfig validation
(rate_limit, body_limit, site checks). Add PartialEq derives to config types.
Include unit tests for ArcSwap swap visibility, invalid config rejection, and
concurrent reload serialization.
This commit is contained in:
2026-06-11 12:42:16 +00:00
parent 468adb21de
commit fbae1c464e
5 changed files with 258 additions and 18 deletions

View File

@@ -1,7 +1,7 @@
use serde::Deserialize;
#[allow(dead_code)]
#[derive(Debug, Clone, Deserialize)]
#[derive(Debug, Clone, Deserialize, PartialEq)]
pub struct StaticConfig {
pub listeners: Vec<ListenerConfig>,
#[serde(default)]
@@ -32,7 +32,7 @@ fn default_shutdown_timeout_secs() -> u64 {
}
#[allow(dead_code)]
#[derive(Debug, Clone, Deserialize)]
#[derive(Debug, Clone, Deserialize, PartialEq)]
pub struct ListenerConfig {
pub bind_addr: String,
#[serde(default = "default_http_port")]
@@ -55,7 +55,7 @@ fn default_https_port() -> u16 {
}
#[allow(dead_code)]
#[derive(Debug, Clone, Deserialize)]
#[derive(Debug, Clone, Deserialize, PartialEq)]
pub struct TlsConfig {
pub mode: String,
#[serde(default)]
@@ -76,7 +76,7 @@ fn default_acme_directory() -> String {
}
#[allow(dead_code)]
#[derive(Debug, Clone, Deserialize)]
#[derive(Debug, Clone, Deserialize, PartialEq)]
pub struct LoggingConfig {
#[serde(default = "default_log_level")]
pub level: String,