use serde::{Deserialize, Serialize};
#[cfg(feature = "observers")]
const fn default_observers_enabled() -> bool {
true
}
#[cfg(feature = "observers")]
const fn default_poll_interval_ms() -> u64 {
100
}
#[cfg(feature = "observers")]
const fn default_batch_size() -> usize {
100
}
#[cfg(feature = "observers")]
const fn default_channel_capacity() -> usize {
1000
}
#[cfg(feature = "observers")]
const fn default_auto_reload() -> bool {
true
}
#[cfg(feature = "observers")]
const fn default_reload_interval_secs() -> u64 {
60
}
#[cfg(feature = "observers")]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(default)]
pub struct ObserverPoolConfig {
#[serde(default = "default_observer_pool_min")]
pub min_connections: u32,
#[serde(default = "default_observer_pool_max")]
pub max_connections: u32,
#[serde(default = "default_observer_acquire_timeout")]
pub acquire_timeout_secs: u64,
}
#[cfg(feature = "observers")]
const fn default_observer_pool_min() -> u32 {
2
}
#[cfg(feature = "observers")]
const fn default_observer_pool_max() -> u32 {
5
}
#[cfg(feature = "observers")]
const fn default_observer_acquire_timeout() -> u64 {
10
}
#[cfg(feature = "observers")]
impl Default for ObserverPoolConfig {
fn default() -> Self {
Self {
min_connections: default_observer_pool_min(),
max_connections: default_observer_pool_max(),
acquire_timeout_secs: default_observer_acquire_timeout(),
}
}
}
#[cfg(feature = "observers")]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ObserverConfig {
#[serde(default = "default_observers_enabled")]
pub enabled: bool,
#[serde(default = "default_poll_interval_ms")]
pub poll_interval_ms: u64,
#[serde(default = "default_batch_size")]
pub batch_size: usize,
#[serde(default = "default_channel_capacity")]
pub channel_capacity: usize,
#[serde(default = "default_auto_reload")]
pub auto_reload: bool,
#[serde(default = "default_reload_interval_secs")]
pub reload_interval_secs: u64,
#[serde(default)]
pub pool: ObserverPoolConfig,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AdmissionConfig {
#[serde(default = "default_admission_max_concurrent")]
pub max_concurrent: usize,
#[serde(default = "default_admission_max_queue_depth")]
pub max_queue_depth: u64,
}
pub(crate) const fn default_admission_max_concurrent() -> usize {
500
}
pub(crate) const fn default_admission_max_queue_depth() -> u64 {
1000
}
#[cfg(all(test, feature = "observers"))]
mod tests {
#![allow(clippy::unwrap_used)]
use super::*;
#[test]
fn observer_pool_config_defaults_are_sensible() {
let cfg = ObserverPoolConfig::default();
assert!(cfg.min_connections >= 1, "observer pool needs at least 1 connection");
assert!(
cfg.max_connections >= cfg.min_connections,
"max_connections ({}) must be >= min_connections ({})",
cfg.max_connections,
cfg.min_connections,
);
assert!(cfg.acquire_timeout_secs > 0, "acquire_timeout_secs should be > 0");
assert!(
cfg.max_connections <= 10,
"observer pool defaults should be small (<=10), got {}",
cfg.max_connections,
);
}
#[test]
fn observer_config_with_pool_section_deserializes() {
let toml = r"
enabled = true
[pool]
min_connections = 3
max_connections = 8
acquire_timeout_secs = 15
";
let cfg: ObserverConfig = toml::from_str(toml).unwrap();
assert_eq!(cfg.pool.min_connections, 3);
assert_eq!(cfg.pool.max_connections, 8);
assert_eq!(cfg.pool.acquire_timeout_secs, 15);
}
#[test]
fn observer_config_pool_defaults_when_section_absent() {
let toml = r"enabled = true";
let cfg: ObserverConfig = toml::from_str(toml).unwrap();
assert_eq!(cfg.pool.min_connections, 2, "default min_connections should be 2");
assert_eq!(cfg.pool.max_connections, 5, "default max_connections should be 5");
assert_eq!(cfg.pool.acquire_timeout_secs, 10, "default acquire_timeout_secs should be 10");
}
}