3 Commits
Author SHA1 Message Date
Nils Andreas Svee f1a50af7d3 fix(reflectors): retain current peers when no candidates respond
Rust CI / cargo fmt (push) Successful in 22s
Rust CI / cargo check (x86_64-unknown-linux-gnu) (push) Failing after 37s
Rust CI / cargo clippy (push) Failing after 37s
Rust CI / cargo test (x86_64-unknown-linux-musl) (push) Failing after 12s
Rust CI / cargo check (x86_64-unknown-linux-musl) (push) Failing after 13s
Rust CI / cargo test (x86_64-unknown-linux-gnu) (push) Failing after 31s
Supply chain / cargo-deny advisories (push) Failing after 3s
Supply chain / cargo-deny bans licenses sources (push) Failing after 2s
Supply chain / actionlint (push) Failing after 3s
Rust CI / cargo doc (push) Failing after 32s
Build binaries / Build (arm-musleabi) (push) Successful in 2m16s
Build binaries / Build (aarch64-musl) (push) Failing after 24m1s
Build binaries / Build (arm-musleabihf) (push) Failing after 51m7s
Build binaries / Build (armv7-musleabihf) (push) Failing after 11m33s
Build binaries / Build (armv7-musleabi) (push) Failing after 11m33s
Build binaries / Build (i686-musl) (push) Successful in 2m6s
Build binaries / Build (mips-musl) (push) Successful in 2m10s
Build binaries / Build (mips64-muslabi64) (push) Successful in 2m5s
Build binaries / Build (mips64el-muslabi64) (push) Successful in 2m12s
Build binaries / Build (mipsel-musl) (push) Successful in 2m10s
Build binaries / Build (riscv64gc-musl) (push) Successful in 2m9s
Build binaries / Build (x86_64-musl) (push) Successful in 1m42s
Restore the pre-probe selection when evaluation finds no usable candidates. Preserve master’s existing selection of smaller candidate sets.
2026-10-14 11:58:07 +07:00
Nils Andreas Svee 5624746914 fix(ratecontroller): account for configured and partial reflector sets
Cap the required delta count at the active peer count using advanced_settings.num_reflectors. Keep requesting reselection when the active set is empty so recovery remains possible.
2026-10-14 11:58:07 +07:00
Nils Andreas Svee 2e24da4bf8 chore: remove unused clock and mutex helpers 2026-10-14 11:58:07 +07:00
4 changed files with 18 additions and 23 deletions

No files matched your search

+9 -3
View File
@@ -491,12 +491,18 @@ impl<S: InterfaceStatsProvider, T: TrafficControlBackend> Ratecontroller<S, T> {
self.state_dl.deltas = down_deltas; self.state_dl.deltas = down_deltas;
self.state_ul.deltas = up_deltas; self.state_ul.deltas = up_deltas;
if self.state_dl.deltas.len() < 5 || self.state_ul.deltas.len() < 5 { let minimum =
usize::from(self.settings.advanced_settings.num_reflectors).min(reflectors.len());
if reflectors.is_empty()
|| self.state_dl.deltas.len() < minimum
|| self.state_ul.deltas.len() < minimum
{
// trigger reselection // trigger reselection
warn!( warn!(
"Not enough delta values (D: {}, U: {}, need 5), triggering reselection", "Not enough delta values (D: {}, U: {}, need {}), triggering reselection",
self.state_dl.deltas.len(), self.state_dl.deltas.len(),
self.state_ul.deltas.len() self.state_ul.deltas.len(),
minimum
); );
let _ = self.reselect_trigger.try_send(true); let _ = self.reselect_trigger.try_send(true);
} }
+8
View File
@@ -167,6 +167,7 @@ impl ReflectorSelector {
let mut next_peers: Vec<IpAddr> = Vec::new(); let mut next_peers: Vec<IpAddr> = Vec::new();
let mut reflectors_peers = self.reflector_peers_lock.write_anyhow()?; let mut reflectors_peers = self.reflector_peers_lock.write_anyhow()?;
let current_peers = reflectors_peers.clone();
// Include all current peers // Include all current peers
for reflector in reflectors_peers.iter() { for reflector in reflectors_peers.iter() {
@@ -236,6 +237,13 @@ impl ReflectorSelector {
candidates.swap(i, j); candidates.swap(i, j);
} }
if candidates.is_empty() {
info!("No usable reflectors, retaining current set");
self.reflector_tx.send(current_peers.clone())?;
*reflectors_peers = current_peers;
continue;
}
if (candidates.len() as u8) < num_reflectors { if (candidates.len() as u8) < num_reflectors {
num_reflectors = candidates.len() as u8; num_reflectors = candidates.len() as u8;
} }
-9
View File
@@ -14,16 +14,11 @@ pub trait Clock {
} }
pub enum Realtime {} pub enum Realtime {}
pub enum Monotonic {}
impl Clock for Realtime { impl Clock for Realtime {
const ID: ClockId = ClockId::Realtime; const ID: ClockId = ClockId::Realtime;
} }
impl Clock for Monotonic {
const ID: ClockId = ClockId::Monotonic;
}
pub struct ClockSample<C> { pub struct ClockSample<C> {
time_s: u64, time_s: u64,
time_ns: u64, time_ns: u64,
@@ -56,10 +51,6 @@ impl<C: Clock> ClockSample<C> {
pub fn as_secs_f64(&self) -> f64 { pub fn as_secs_f64(&self) -> f64 {
self.time_s as f64 + self.time_ns as f64 / 1_000_000_000.0 self.time_s as f64 + self.time_ns as f64 / 1_000_000_000.0
} }
pub fn to_milliseconds(&self) -> u64 {
(self.time_s * 1000) + (self.time_ns / 1000000)
}
} }
impl ClockSample<Realtime> { impl ClockSample<Realtime> {
+1 -11
View File
@@ -3,20 +3,10 @@
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
use anyhow::anyhow; use anyhow::anyhow;
use std::sync::{Arc, Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard}; use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
pub type ArcRwLock<T> = Arc<RwLock<T>>; pub type ArcRwLock<T> = Arc<RwLock<T>>;
pub trait MutexExt<T> {
fn lock_anyhow(&self) -> anyhow::Result<MutexGuard<'_, T>>;
}
impl<T> MutexExt<T> for Mutex<T> {
fn lock_anyhow(&self) -> anyhow::Result<MutexGuard<'_, T>> {
self.lock().map_err(|e| anyhow!("mutex poisoned: {e}"))
}
}
pub trait RwLockExt<T> { pub trait RwLockExt<T> {
fn read_anyhow(&self) -> anyhow::Result<RwLockReadGuard<'_, T>>; fn read_anyhow(&self) -> anyhow::Result<RwLockReadGuard<'_, T>>;
fn write_anyhow(&self) -> anyhow::Result<RwLockWriteGuard<'_, T>>; fn write_anyhow(&self) -> anyhow::Result<RwLockWriteGuard<'_, T>>;