From ce8b43d2e47062b28c6235fec5b8c8fdfb68c965 Mon Sep 17 00:00:00 2001 From: Anant Vindal Date: Thu, 10 Sep 2026 15:21:51 +0200 Subject: [PATCH 1/2] feat: rejection duration after threshold breach --- src/cli.rs | 9 +++++++++ src/handlers/http/resource_check.rs | 3 +++ 2 files changed, 12 insertions(+) diff --git a/src/cli.rs b/src/cli.rs index e4dc73495..25db7e053 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -508,6 +508,15 @@ pub struct Options { )] pub resource_check_interval: u64, + #[arg( + long, + env = "P_REJECTION_DURATION", + default_value = "30", + value_parser = validation::validate_seconds, + help = "Post threshold breach, reject requests for" + )] + pub rejection_duration: u64, + #[arg( long, env = "P_MEMORY_THRESHOLD", diff --git a/src/handlers/http/resource_check.rs b/src/handlers/http/resource_check.rs index 412367465..fffb9805f 100644 --- a/src/handlers/http/resource_check.rs +++ b/src/handlers/http/resource_check.rs @@ -80,6 +80,9 @@ pub fn spawn_resource_monitor(shutdown_rx: tokio::sync::oneshot::Receiver<()>) { info!("Resource utilization back to normal - requests will be accepted"); } else { warn!("Resource utilization too high - requests will be rejected"); + + // sleep for rejection duration (+ the check interval) + tokio::time::sleep(Duration::from_secs(PARSEABLE.options.rejection_duration)).await; } }, _ = process_metrics_interval.tick() => { From d2a20748eedf26f30d53b7f9bdf0d19f345da505 Mon Sep 17 00:00:00 2001 From: Anant Vindal Date: Thu, 10 Sep 2026 15:35:23 +0200 Subject: [PATCH 2/2] coderabbit comment --- src/handlers/http/resource_check.rs | 56 ++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/src/handlers/http/resource_check.rs b/src/handlers/http/resource_check.rs index fffb9805f..2cd058a25 100644 --- a/src/handlers/http/resource_check.rs +++ b/src/handlers/http/resource_check.rs @@ -40,6 +40,27 @@ const PROCESS_METRICS_SAMPLE_INTERVAL: Duration = Duration::from_secs(5); static SERVER_OK: LazyLock> = LazyLock::new(|| Arc::new(AtomicBool::new(true))); +async fn sample_process_metrics() { + refresh_sys_info(); + let process_metrics = tokio::task::spawn_blocking(|| { + let sys = SYS_INFO.lock().unwrap(); + let total_mem = if let Some(cgroup) = sys.cgroup_limits() { + cgroup.total_memory + } else { + sys.total_memory() + }; + sysinfo::get_current_pid() + .ok() + .and_then(|pid| sys.process(pid)) + .map(|process| (process.cpu_usage() as f64, process.memory(), total_mem)) + }) + .await + .unwrap(); + if let Some((cpu_usage, memory_bytes, total_mem)) = process_metrics { + record_process_metrics_sample(cpu_usage, memory_bytes, total_mem); + } +} + /// Spawn a background task to monitor system resources pub fn spawn_resource_monitor(shutdown_rx: tokio::sync::oneshot::Receiver<()>) { tokio::spawn(async move { @@ -82,26 +103,27 @@ pub fn spawn_resource_monitor(shutdown_rx: tokio::sync::oneshot::Receiver<()>) { warn!("Resource utilization too high - requests will be rejected"); // sleep for rejection duration (+ the check interval) - tokio::time::sleep(Duration::from_secs(PARSEABLE.options.rejection_duration)).await; + let rejection_delay = tokio::time::sleep(Duration::from_secs( + PARSEABLE.options.rejection_duration, + )); + tokio::pin!(rejection_delay); + + loop { + select! { + _ = &mut rejection_delay => break, + _ = process_metrics_interval.tick() => { + sample_process_metrics().await; + }, + _ = &mut shutdown_rx => { + trace!("Resource monitor shutting down"); + return; + } + } + } } }, _ = process_metrics_interval.tick() => { - refresh_sys_info(); - let process_metrics = tokio::task::spawn_blocking(|| { - let sys = SYS_INFO.lock().unwrap(); - let total_mem = if let Some(cgroup) = sys.cgroup_limits() { - cgroup.total_memory - } else { - sys.total_memory() - }; - sysinfo::get_current_pid() - .ok() - .and_then(|pid| sys.process(pid)) - .map(|process| (process.cpu_usage() as f64, process.memory(), total_mem)) - }).await.unwrap(); - if let Some((cpu_usage, memory_bytes, total_mem)) = process_metrics { - record_process_metrics_sample(cpu_usage, memory_bytes, total_mem); - } + sample_process_metrics().await; }, _ = &mut shutdown_rx => { trace!("Resource monitor shutting down");