use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PoolPressureMonitorConfig {
#[serde(default)]
pub enabled: bool,
#[serde(default = "default_min_pool_size")]
pub min_pool_size: u32,
#[serde(default = "default_max_pool_size")]
pub max_pool_size: u32,
#[serde(default = "default_target_queue_depth")]
pub target_queue_depth: u32,
#[serde(default = "default_scale_up_step")]
pub scale_up_step: u32,
#[serde(default = "default_scale_down_step")]
pub scale_down_step: u32,
#[serde(default = "default_scale_down_idle_ratio")]
pub scale_down_idle_ratio: f64,
#[serde(default = "default_tuning_interval_ms")]
pub tuning_interval_ms: u64,
#[serde(default = "default_samples_before_action")]
pub samples_before_action: u32,
}
const fn default_min_pool_size() -> u32 {
5
}
const fn default_max_pool_size() -> u32 {
50
}
const fn default_target_queue_depth() -> u32 {
3
}
const fn default_scale_up_step() -> u32 {
5
}
const fn default_scale_down_step() -> u32 {
2
}
const fn default_scale_down_idle_ratio() -> f64 {
0.5
}
const fn default_tuning_interval_ms() -> u64 {
30_000
}
const fn default_samples_before_action() -> u32 {
3
}
impl Default for PoolPressureMonitorConfig {
fn default() -> Self {
Self {
enabled: false,
min_pool_size: default_min_pool_size(),
max_pool_size: default_max_pool_size(),
target_queue_depth: default_target_queue_depth(),
scale_up_step: default_scale_up_step(),
scale_down_step: default_scale_down_step(),
scale_down_idle_ratio: default_scale_down_idle_ratio(),
tuning_interval_ms: default_tuning_interval_ms(),
samples_before_action: default_samples_before_action(),
}
}
}
#[deprecated(since = "2.0.1", note = "Use PoolPressureMonitorConfig")]
pub type PoolTuningConfig = PoolPressureMonitorConfig;
impl PoolPressureMonitorConfig {
#[must_use = "builder does nothing until .build() is called"]
pub fn builder() -> PoolPressureMonitorConfigBuilder {
PoolPressureMonitorConfigBuilder::default()
}
pub fn validate(&self) -> Result<(), String> {
if self.min_pool_size >= self.max_pool_size {
return Err(format!(
"pool_tuning: min_pool_size ({}) must be less than max_pool_size ({})",
self.min_pool_size, self.max_pool_size
));
}
if self.scale_up_step == 0 {
return Err("pool_tuning: scale_up_step must be > 0".to_string());
}
if self.scale_down_step == 0 {
return Err("pool_tuning: scale_down_step must be > 0".to_string());
}
if !(0.0..=1.0).contains(&self.scale_down_idle_ratio) {
return Err(format!(
"pool_tuning: scale_down_idle_ratio ({}) must be in [0.0, 1.0]",
self.scale_down_idle_ratio
));
}
if self.tuning_interval_ms < 100 {
return Err(format!(
"pool_tuning: tuning_interval_ms ({}) must be >= 100",
self.tuning_interval_ms
));
}
Ok(())
}
}
#[derive(Debug, Default)]
pub struct PoolPressureMonitorConfigBuilder {
inner: PoolPressureMonitorConfig,
}
impl PoolPressureMonitorConfigBuilder {
#[must_use = "builder method returns modified builder"]
pub const fn enabled(mut self, enabled: bool) -> Self {
self.inner.enabled = enabled;
self
}
#[must_use = "builder method returns modified builder"]
pub const fn min_pool_size(mut self, min_pool_size: u32) -> Self {
self.inner.min_pool_size = min_pool_size;
self
}
#[must_use = "builder method returns modified builder"]
pub const fn max_pool_size(mut self, max_pool_size: u32) -> Self {
self.inner.max_pool_size = max_pool_size;
self
}
#[must_use = "builder method returns modified builder"]
pub const fn target_queue_depth(mut self, target_queue_depth: u32) -> Self {
self.inner.target_queue_depth = target_queue_depth;
self
}
#[must_use = "builder method returns modified builder"]
pub const fn scale_up_step(mut self, scale_up_step: u32) -> Self {
self.inner.scale_up_step = scale_up_step;
self
}
#[must_use = "builder method returns modified builder"]
pub const fn scale_down_step(mut self, scale_down_step: u32) -> Self {
self.inner.scale_down_step = scale_down_step;
self
}
#[must_use = "builder method returns modified builder"]
pub const fn scale_down_idle_ratio(mut self, scale_down_idle_ratio: f64) -> Self {
self.inner.scale_down_idle_ratio = scale_down_idle_ratio;
self
}
#[must_use = "builder method returns modified builder"]
pub const fn tuning_interval_ms(mut self, tuning_interval_ms: u64) -> Self {
self.inner.tuning_interval_ms = tuning_interval_ms;
self
}
#[must_use = "builder method returns modified builder"]
pub const fn samples_before_action(mut self, samples_before_action: u32) -> Self {
self.inner.samples_before_action = samples_before_action;
self
}
#[must_use = "building a config that is not used has no effect"]
pub const fn build(self) -> PoolPressureMonitorConfig {
self.inner
}
}