fix(metrics): preserve stop event and restore after controller exit
Build / build (pull_request) Failing after 4s
DevSkim / DevSkim (pull_request) Failing after 1m20s
rust-clippy analyze / Run rust-clippy analyzing (pull_request) Failing after 1m41s

This commit is contained in:
Nils Andreas Svee committed 2026-09-24 23:17:20 +07:00
1 parent 6773b6ed4f
commit 34e60e4742
3 files changed
+31 -14

No files matched your search

+12 -10
View File
@@ -264,6 +264,7 @@ fn run(settings: &Settings) -> anyhow::Result<()> {
let (reselect_tx, reselect_rx) = flume::bounded(1); let (reselect_tx, reselect_rx) = flume::bounded(1);
let dropped = Arc::new(AtomicU32::new(0)); let dropped = Arc::new(AtomicU32::new(0));
let metrics_shutdown = Arc::new(AtomicBool::new(false));
let (metrics_tx, metrics_thread_handle) = if settings.observability.enabled { let (metrics_tx, metrics_thread_handle) = if settings.observability.enabled {
let (tx, rx) = flume::bounded(1000); let (tx, rx) = flume::bounded(1000);
@@ -271,6 +272,7 @@ fn run(settings: &Settings) -> anyhow::Result<()> {
settings: settings.clone(), settings: settings.clone(),
metrics_rx: rx, metrics_rx: rx,
metrics_dropped: Arc::clone(&dropped), metrics_dropped: Arc::clone(&dropped),
shutdown_requested: Arc::clone(&metrics_shutdown),
}; };
let err_tx = error_tx.clone(); let err_tx = error_tx.clone();
let handle = thread::Builder::new() let handle = thread::Builder::new()
@@ -420,7 +422,7 @@ fn run(settings: &Settings) -> anyhow::Result<()> {
)?; )?;
let err_tx = error_tx.clone(); let err_tx = error_tx.clone();
thread::Builder::new() let ratecontroller_thread_handle = thread::Builder::new()
.name("ratecontroller".to_string()) .name("ratecontroller".to_string())
.spawn(move || { .spawn(move || {
if let Err(error) = ratecontroller.run() { if let Err(error) = ratecontroller.run() {
@@ -444,10 +446,17 @@ fn run(settings: &Settings) -> anyhow::Result<()> {
tags: &[], tags: &[],
}); });
// Drop all MetricsSender instances and the raw tx so the metrics channel let _ = ratecontroller_thread_handle.join();
// disconnects once all worker threads also drop their copies. restore_shaper(
settings,
&mut main_traffic_control,
&down_shaper,
&up_shaper,
);
drop(main_event_metrics); drop(main_event_metrics);
drop(metrics_tx); drop(metrics_tx);
metrics_shutdown.store(true, Ordering::Relaxed);
if let Some(handle) = metrics_thread_handle { if let Some(handle) = metrics_thread_handle {
let deadline = Instant::now() + Duration::from_secs(1); let deadline = Instant::now() + Duration::from_secs(1);
@@ -461,13 +470,6 @@ fn run(settings: &Settings) -> anyhow::Result<()> {
} }
} }
restore_shaper(
settings,
&mut main_traffic_control,
&down_shaper,
&up_shaper,
);
result result
} }
+3 -3
View File
@@ -2,7 +2,6 @@
// //
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
use crate::SHUTDOWN;
use crate::settings::Settings; use crate::settings::Settings;
use crate::settings::{MeasurementType, ObservabilityProtocol}; use crate::settings::{MeasurementType, ObservabilityProtocol};
use crate::time::Time; use crate::time::Time;
@@ -12,7 +11,7 @@ use rustix::time::ClockId;
use std::fmt::Write; use std::fmt::Write;
use std::net::{IpAddr, TcpStream, UdpSocket}; use std::net::{IpAddr, TcpStream, UdpSocket};
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
const MAX_RECONNECT_BACKOFF: u64 = 60; const MAX_RECONNECT_BACKOFF: u64 = 60;
@@ -228,6 +227,7 @@ pub struct Metrics {
pub settings: Settings, pub settings: Settings,
pub metrics_dropped: Arc<AtomicU32>, pub metrics_dropped: Arc<AtomicU32>,
pub metrics_rx: Receiver<(Metric, u64)>, pub metrics_rx: Receiver<(Metric, u64)>,
pub shutdown_requested: Arc<AtomicBool>,
} }
impl Metrics { impl Metrics {
@@ -261,7 +261,7 @@ impl Metrics {
let mut last_flush = Instant::now(); let mut last_flush = Instant::now();
loop { loop {
if SHUTDOWN.load(Ordering::Relaxed) { if self.shutdown_requested.load(Ordering::Relaxed) {
let deadline = shutdown_deadline let deadline = shutdown_deadline
.get_or_insert_with(|| Instant::now() + Duration::from_millis(400)); .get_or_insert_with(|| Instant::now() + Duration::from_millis(400));
if Instant::now() >= *deadline { if Instant::now() >= *deadline {
+16 -1
View File
@@ -336,7 +336,22 @@ impl<S: InterfaceStatsProvider, T: TrafficControlBackend> Ratecontroller<S, T> {
info!("Rate controller shutting down"); info!("Rate controller shutting down");
return Ok(()); return Ok(());
} }
sleep(sleep_time); let wake_at = Instant::now() + sleep_time;
while Instant::now() < wake_at {
if SHUTDOWN.load(Ordering::Relaxed) {
info!("Rate controller shutting down");
return Ok(());
}
sleep(
wake_at
.saturating_duration_since(Instant::now())
.min(Duration::from_millis(100)),
);
}
if SHUTDOWN.load(Ordering::Relaxed) {
info!("Rate controller shutting down");
return Ok(());
}
let now_t = Instant::now(); let now_t = Instant::now();
if now_t.duration_since(lastchg_t).as_secs_f64() if now_t.duration_since(lastchg_t).as_secs_f64()