Add flap dampening to parent selection

Track parent switch frequency in a sliding window. When switches exceed
a configurable threshold (default 4 in 60s), impose an extended hold-down
period (default 120s) that prevents non-mandatory parent changes.

Mandatory switches (parent loss, root change, shouldn't-be-root) bypass
dampening. The flap counter resets when the window expires naturally.

Implements TASK-2026-0030 / IDEA-0013.
This commit is contained in:
Johnathan Corgan
2026-02-23 20:00:58 +00:00
parent 5d72e7cee1
commit 94c0e19951
5 changed files with 340 additions and 4 deletions
+15
View File
@@ -210,6 +210,15 @@ pub struct TreeConfig {
/// tree has stabilized. Set to 0 to disable.
#[serde(default = "TreeConfig::default_reeval_interval_secs")]
pub reeval_interval_secs: u64,
/// Flap dampening: max parent switches before extended hold-down (`node.tree.flap_threshold`).
#[serde(default = "TreeConfig::default_flap_threshold")]
pub flap_threshold: u32,
/// Flap dampening: window in seconds for counting switches (`node.tree.flap_window_secs`).
#[serde(default = "TreeConfig::default_flap_window_secs")]
pub flap_window_secs: u64,
/// Flap dampening: extended hold-down duration in seconds (`node.tree.flap_dampening_secs`).
#[serde(default = "TreeConfig::default_flap_dampening_secs")]
pub flap_dampening_secs: u64,
}
impl Default for TreeConfig {
@@ -219,6 +228,9 @@ impl Default for TreeConfig {
parent_hysteresis: 0.2,
hold_down_secs: 30,
reeval_interval_secs: 60,
flap_threshold: 4,
flap_window_secs: 60,
flap_dampening_secs: 120,
}
}
}
@@ -228,6 +240,9 @@ impl TreeConfig {
fn default_parent_hysteresis() -> f64 { 0.2 }
fn default_hold_down_secs() -> u64 { 30 }
fn default_reeval_interval_secs() -> u64 { 60 }
fn default_flap_threshold() -> u32 { 4 }
fn default_flap_window_secs() -> u64 { 60 }
fn default_flap_dampening_secs() -> u64 { 120 }
}
/// Bloom filter (`node.bloom.*`).