Fairness Regression fixes

This commit is contained in:
Alexey
2026-04-21 01:11:43 +03:00
parent aace0129f8
commit 926e3aa987
17 changed files with 244 additions and 71 deletions
+44 -29
View File
@@ -12,6 +12,7 @@ pub(crate) struct PressureSignals {
#[derive(Debug, Clone)]
pub(crate) struct PressureConfig {
pub(crate) backpressure_enabled: bool,
pub(crate) evaluate_every_rounds: u32,
pub(crate) transition_hysteresis_rounds: u8,
pub(crate) standing_ratio_pressured_pct: u8,
@@ -32,6 +33,7 @@ pub(crate) struct PressureConfig {
impl Default for PressureConfig {
fn default() -> Self {
Self {
backpressure_enabled: true,
evaluate_every_rounds: 8,
transition_hysteresis_rounds: 3,
standing_ratio_pressured_pct: 20,
@@ -99,6 +101,13 @@ impl PressureEvaluator {
force: bool,
) -> PressureState {
self.rotate_window_if_needed(now, cfg);
if !cfg.backpressure_enabled {
self.state = PressureState::Normal;
self.candidate_state = PressureState::Normal;
self.candidate_hits = 0;
self.rounds_since_eval = 0;
return self.state;
}
self.rounds_since_eval = self.rounds_since_eval.saturating_add(1);
if !force && self.rounds_since_eval < cfg.evaluate_every_rounds.max(1) {
return self.state;
@@ -133,6 +142,10 @@ impl PressureEvaluator {
max_total_queued_bytes: u64,
signals: PressureSignals,
) -> PressureState {
if !cfg.backpressure_enabled {
return PressureState::Normal;
}
let queue_ratio_pct = if max_total_queued_bytes == 0 {
100
} else {
@@ -146,57 +159,59 @@ impl PressureEvaluator {
((signals.standing_flows.saturating_mul(100)) / signals.active_flows).min(100) as u8
};
let mut pressured = false;
let mut saturated = false;
let mut pressure_score = 0u8;
let queue_saturated_pct = cfg
.queue_ratio_shedding_pct
.min(cfg.queue_ratio_saturated_pct);
if queue_ratio_pct >= cfg.queue_ratio_pressured_pct {
pressured = true;
pressure_score = pressure_score.max(1);
}
if queue_ratio_pct >= queue_saturated_pct {
saturated = true;
if queue_ratio_pct >= cfg.queue_ratio_shedding_pct {
pressure_score = pressure_score.max(2);
}
if queue_ratio_pct >= cfg.queue_ratio_saturated_pct {
pressure_score = pressure_score.max(3);
}
let standing_saturated_pct = cfg
.standing_ratio_shedding_pct
.min(cfg.standing_ratio_saturated_pct);
if standing_ratio_pct >= cfg.standing_ratio_pressured_pct {
pressured = true;
pressure_score = pressure_score.max(1);
}
if standing_ratio_pct >= standing_saturated_pct {
saturated = true;
if standing_ratio_pct >= cfg.standing_ratio_shedding_pct {
pressure_score = pressure_score.max(2);
}
if standing_ratio_pct >= cfg.standing_ratio_saturated_pct {
pressure_score = pressure_score.max(3);
}
let rejects_saturated = cfg.rejects_shedding.min(cfg.rejects_saturated);
if self.admission_rejects_window >= cfg.rejects_pressured {
pressured = true;
pressure_score = pressure_score.max(1);
}
if self.admission_rejects_window >= rejects_saturated {
saturated = true;
if self.admission_rejects_window >= cfg.rejects_shedding {
pressure_score = pressure_score.max(2);
}
if self.admission_rejects_window >= cfg.rejects_saturated {
pressure_score = pressure_score.max(3);
}
let stalls_saturated = cfg.stalls_shedding.min(cfg.stalls_saturated);
if self.route_stalls_window >= cfg.stalls_pressured {
pressured = true;
pressure_score = pressure_score.max(1);
}
if self.route_stalls_window >= stalls_saturated {
saturated = true;
if self.route_stalls_window >= cfg.stalls_shedding {
pressure_score = pressure_score.max(2);
}
if self.route_stalls_window >= cfg.stalls_saturated {
pressure_score = pressure_score.max(3);
}
if signals.backpressured_flows > signals.active_flows.saturating_div(2)
&& signals.active_flows > 0
{
pressured = true;
pressure_score = pressure_score.max(2);
}
if saturated {
PressureState::Saturated
} else if pressured {
PressureState::Pressured
} else {
PressureState::Normal
match pressure_score {
0 => PressureState::Normal,
1 => PressureState::Pressured,
2 => PressureState::Shedding,
_ => PressureState::Saturated,
}
}
@@ -14,6 +14,7 @@ use super::pressure::{PressureConfig, PressureEvaluator, PressureSignals};
#[derive(Debug, Clone)]
pub(crate) struct WorkerFairnessConfig {
pub(crate) worker_id: u16,
pub(crate) backpressure_enabled: bool,
pub(crate) max_active_flows: usize,
pub(crate) max_total_queued_bytes: u64,
pub(crate) max_flow_queued_bytes: u64,
@@ -36,6 +37,7 @@ impl Default for WorkerFairnessConfig {
fn default() -> Self {
Self {
worker_id: 0,
backpressure_enabled: true,
max_active_flows: 4096,
max_total_queued_bytes: 16 * 1024 * 1024,
max_flow_queued_bytes: 512 * 1024,
@@ -107,7 +109,8 @@ pub(crate) struct WorkerFairnessState {
}
impl WorkerFairnessState {
pub(crate) fn new(config: WorkerFairnessConfig, now: Instant) -> Self {
pub(crate) fn new(mut config: WorkerFairnessConfig, now: Instant) -> Self {
config.pressure.backpressure_enabled = config.backpressure_enabled;
let bucket_count = config.soft_bucket_count.max(1);
Self {
config,
@@ -134,6 +137,12 @@ impl WorkerFairnessState {
self.pressure.state()
}
pub(crate) fn set_backpressure_enabled(&mut self, enabled: bool) {
self.config.backpressure_enabled = enabled;
self.config.pressure.backpressure_enabled = enabled;
self.evaluate_pressure(Instant::now(), true);
}
pub(crate) fn snapshot(&self) -> WorkerFairnessSnapshot {
WorkerFairnessSnapshot {
pressure_state: self.pressure.state(),
@@ -166,7 +175,7 @@ impl WorkerFairnessState {
};
let frame_bytes = frame.queued_bytes();
if self.pressure.state() == PressureState::Saturated {
if self.config.backpressure_enabled && self.pressure.state() == PressureState::Saturated {
self.pressure
.note_admission_reject(now, &self.config.pressure);
self.enqueue_rejects = self.enqueue_rejects.saturating_add(1);
@@ -231,7 +240,8 @@ impl WorkerFairnessState {
return AdmissionDecision::RejectFlowCap;
}
if self.pressure.state() >= PressureState::Shedding
if self.config.backpressure_enabled
&& self.pressure.state() >= PressureState::Shedding
&& entry.fairness.standing_state == StandingQueueState::Standing
{
self.pressure
@@ -422,8 +432,10 @@ impl WorkerFairnessState {
DispatchAction::Continue
}
DispatchFeedback::QueueFull => {
self.pressure.note_route_stall(now, &self.config.pressure);
self.downstream_stalls = self.downstream_stalls.saturating_add(1);
if self.config.backpressure_enabled {
self.pressure.note_route_stall(now, &self.config.pressure);
self.downstream_stalls = self.downstream_stalls.saturating_add(1);
}
let state = self.pressure.state();
let Some(flow) = self.flows.get_mut(&conn_id) else {
self.evaluate_pressure(now, true);
@@ -433,16 +445,19 @@ impl WorkerFairnessState {
let before_membership = Self::flow_membership(&flow.fairness);
let mut enqueue_active = false;
flow.fairness.consecutive_stalls =
flow.fairness.consecutive_stalls.saturating_add(1);
flow.fairness.scheduler_state = FlowSchedulerState::Backpressured;
flow.fairness.pressure_class = FlowPressureClass::Backpressured;
if self.config.backpressure_enabled {
flow.fairness.consecutive_stalls =
flow.fairness.consecutive_stalls.saturating_add(1);
flow.fairness.scheduler_state = FlowSchedulerState::Backpressured;
flow.fairness.pressure_class = FlowPressureClass::Backpressured;
}
let should_shed_frame = matches!(state, PressureState::Saturated)
|| (matches!(state, PressureState::Shedding)
&& flow.fairness.standing_state == StandingQueueState::Standing
&& flow.fairness.consecutive_stalls
>= self.config.max_consecutive_stalls_before_shed);
let should_shed_frame = self.config.backpressure_enabled
&& (matches!(state, PressureState::Saturated)
|| (matches!(state, PressureState::Shedding)
&& flow.fairness.standing_state == StandingQueueState::Standing
&& flow.fairness.consecutive_stalls
>= self.config.max_consecutive_stalls_before_shed));
if should_shed_frame {
self.shed_drops = self.shed_drops.saturating_add(1);
@@ -467,8 +482,9 @@ impl WorkerFairnessState {
Self::classify_flow(&self.config, state, now, &mut flow.fairness);
let after_membership = Self::flow_membership(&flow.fairness);
let should_close_flow = flow.fairness.consecutive_stalls
>= self.config.max_consecutive_stalls_before_close
let should_close_flow = self.config.backpressure_enabled
&& flow.fairness.consecutive_stalls
>= self.config.max_consecutive_stalls_before_close
&& self.pressure.state() == PressureState::Saturated;
(
before_membership,