mirror of
https://github.com/jmcorgan/fips.git
synced 2026-08-09 08:14:42 +00:00
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:
@@ -374,6 +374,11 @@ impl Node {
|
||||
let mut tree_state = TreeState::new(node_addr);
|
||||
tree_state.set_parent_hysteresis(config.node.tree.parent_hysteresis);
|
||||
tree_state.set_hold_down(config.node.tree.hold_down_secs);
|
||||
tree_state.set_flap_dampening(
|
||||
config.node.tree.flap_threshold,
|
||||
config.node.tree.flap_window_secs,
|
||||
config.node.tree.flap_dampening_secs,
|
||||
);
|
||||
tree_state
|
||||
.sign_declaration(&identity)
|
||||
.expect("signing own declaration should never fail");
|
||||
@@ -459,6 +464,11 @@ impl Node {
|
||||
let mut tree_state = TreeState::new(node_addr);
|
||||
tree_state.set_parent_hysteresis(config.node.tree.parent_hysteresis);
|
||||
tree_state.set_hold_down(config.node.tree.hold_down_secs);
|
||||
tree_state.set_flap_dampening(
|
||||
config.node.tree.flap_threshold,
|
||||
config.node.tree.flap_window_secs,
|
||||
config.node.tree.flap_dampening_secs,
|
||||
);
|
||||
tree_state
|
||||
.sign_declaration(&identity)
|
||||
.expect("signing own declaration should never fail");
|
||||
|
||||
+8
-2
@@ -207,7 +207,7 @@ impl Node {
|
||||
.map(|d| d.as_secs())
|
||||
.unwrap_or(0);
|
||||
|
||||
self.tree_state.set_parent(new_parent, new_seq, timestamp);
|
||||
let flap_dampened = self.tree_state.set_parent(new_parent, new_seq, timestamp);
|
||||
if let Err(e) = self.tree_state.sign_declaration(&self.identity) {
|
||||
warn!(error = %e, "Failed to sign declaration after parent switch");
|
||||
return;
|
||||
@@ -222,6 +222,9 @@ impl Node {
|
||||
depth = self.tree_state.my_coords().depth(),
|
||||
"Parent switched, flushed coord cache, announcing to all peers"
|
||||
);
|
||||
if flap_dampened {
|
||||
warn!("Flap dampening engaged: excessive parent switches detected");
|
||||
}
|
||||
|
||||
self.send_tree_announce_to_all().await;
|
||||
|
||||
@@ -318,7 +321,7 @@ impl Node {
|
||||
.map(|d| d.as_secs())
|
||||
.unwrap_or(0);
|
||||
|
||||
self.tree_state.set_parent(new_parent, new_seq, timestamp);
|
||||
let flap_dampened = self.tree_state.set_parent(new_parent, new_seq, timestamp);
|
||||
if let Err(e) = self.tree_state.sign_declaration(&self.identity) {
|
||||
warn!(error = %e, "Failed to sign declaration after periodic parent re-eval");
|
||||
return;
|
||||
@@ -334,6 +337,9 @@ impl Node {
|
||||
trigger = "periodic",
|
||||
"Parent switched via periodic cost re-evaluation"
|
||||
);
|
||||
if flap_dampened {
|
||||
warn!("Flap dampening engaged: excessive parent switches detected");
|
||||
}
|
||||
|
||||
self.send_tree_announce_to_all().await;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user