mirror of
https://github.com/jmcorgan/fips.git
synced 2026-07-30 19:46:15 +00:00
node: home the peering concept; relocate the connection-retry schedule
Create src/node/peering/ as the home for the peer desired-state (homeostatic reconciler) concept and move the cross-attempt connection retry schedule into it: RetryState plus schedule_retry / schedule_reconnect / process_pending_retries. Mechanical relocation only. The methods remain inherent on Node; the retry_count must persist across re-dials (a fresh connection is created each attempt), which is why the schedule belongs in the peering home rather than on a per-connection type. The one-level-deeper module path requires pub(super) -> pub(in crate::node) to preserve the prior scope, plus module-path fixups at the reference sites. No behavior change; unit test count unchanged (1596).
This commit is contained in:
@@ -2242,7 +2242,7 @@ impl Node {
|
|||||||
.or_insert_with(|| peer_identity.short_npub());
|
.or_insert_with(|| peer_identity.short_npub());
|
||||||
self.register_identity(node_addr, peer_identity.pubkey_full());
|
self.register_identity(node_addr, peer_identity.pubkey_full());
|
||||||
|
|
||||||
let mut state = super::retry::RetryState::new(PeerConfig {
|
let mut state = super::peering::retry::RetryState::new(PeerConfig {
|
||||||
npub: npub.clone(),
|
npub: npub.clone(),
|
||||||
alias: None,
|
alias: None,
|
||||||
addresses,
|
addresses,
|
||||||
|
|||||||
+3
-3
@@ -15,10 +15,10 @@ pub(crate) mod encrypt_worker;
|
|||||||
mod handlers;
|
mod handlers;
|
||||||
mod lifecycle;
|
mod lifecycle;
|
||||||
pub(crate) mod metrics;
|
pub(crate) mod metrics;
|
||||||
|
mod peering;
|
||||||
mod rate_limit;
|
mod rate_limit;
|
||||||
pub(crate) mod reject;
|
pub(crate) mod reject;
|
||||||
mod reloadable;
|
mod reloadable;
|
||||||
mod retry;
|
|
||||||
pub(crate) mod session;
|
pub(crate) mod session;
|
||||||
pub(crate) mod stats;
|
pub(crate) mod stats;
|
||||||
pub(crate) mod stats_history;
|
pub(crate) mod stats_history;
|
||||||
@@ -450,7 +450,7 @@ pub struct Node {
|
|||||||
/// Keyed by NodeAddr. Entries are created when a handshake times out
|
/// Keyed by NodeAddr. Entries are created when a handshake times out
|
||||||
/// or fails, and removed on successful promotion or when max retries
|
/// or fails, and removed on successful promotion or when max retries
|
||||||
/// are exhausted.
|
/// are exhausted.
|
||||||
retry_pending: HashMap<NodeAddr, retry::RetryState>,
|
retry_pending: HashMap<NodeAddr, peering::retry::RetryState>,
|
||||||
|
|
||||||
// === Periodic Parent Re-evaluation ===
|
// === Periodic Parent Re-evaluation ===
|
||||||
/// Timestamp of last periodic parent re-evaluation (for pacing).
|
/// Timestamp of last periodic parent re-evaluation (for pacing).
|
||||||
@@ -2496,7 +2496,7 @@ impl Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Iterate over retry state for diagnostics.
|
/// Iterate over retry state for diagnostics.
|
||||||
pub fn retry_state_iter(&self) -> impl Iterator<Item = (&NodeAddr, &retry::RetryState)> {
|
pub fn retry_state_iter(&self) -> impl Iterator<Item = (&NodeAddr, &peering::retry::RetryState)> {
|
||||||
self.retry_pending.iter()
|
self.retry_pending.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
//! Peering homeostasis — the desired-state controller for the node's peer set.
|
||||||
|
//!
|
||||||
|
//! This module is the home for the peering-reconciler concept: config defines a
|
||||||
|
//! desired peer set; the reconciler converges the observed set toward it
|
||||||
|
//! (auto-connect floor, overlay pool, transport-neighbor growth) under the
|
||||||
|
//! `node.limits` ceiling. Startup and steady-state are the same loop.
|
||||||
|
//!
|
||||||
|
//! The cross-attempt retry schedule (`retry.rs`) lives here because a fresh
|
||||||
|
//! connection is created per re-dial, so the escalating backoff count must
|
||||||
|
//! persist in the reconciler, not per-connection.
|
||||||
|
|
||||||
|
pub(in crate::node) mod retry;
|
||||||
@@ -4,10 +4,10 @@
|
|||||||
//! automatically retry with exponential backoff. Retry state lives on Node
|
//! automatically retry with exponential backoff. Retry state lives on Node
|
||||||
//! (not PeerConnection) because each retry creates a fresh connection.
|
//! (not PeerConnection) because each retry creates a fresh connection.
|
||||||
|
|
||||||
use super::{Node, NodeError};
|
|
||||||
use crate::PeerIdentity;
|
use crate::PeerIdentity;
|
||||||
use crate::config::PeerConfig;
|
use crate::config::PeerConfig;
|
||||||
use crate::identity::NodeAddr;
|
use crate::identity::NodeAddr;
|
||||||
|
use crate::node::{Node, NodeError};
|
||||||
use crate::proto::fmp::backoff_ms;
|
use crate::proto::fmp::backoff_ms;
|
||||||
use tracing::{debug, info, warn};
|
use tracing::{debug, info, warn};
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ impl Node {
|
|||||||
/// have not been exhausted (unless `reconnect` is true, which retries
|
/// have not been exhausted (unless `reconnect` is true, which retries
|
||||||
/// indefinitely). Does nothing if the peer is already connected or has
|
/// indefinitely). Does nothing if the peer is already connected or has
|
||||||
/// a connection in progress.
|
/// a connection in progress.
|
||||||
pub(super) fn schedule_retry(&mut self, node_addr: NodeAddr, now_ms: u64) {
|
pub(in crate::node) fn schedule_retry(&mut self, node_addr: NodeAddr, now_ms: u64) {
|
||||||
let retry_cfg = &self.config().node.retry;
|
let retry_cfg = &self.config().node.retry;
|
||||||
let max_retries = retry_cfg.max_retries;
|
let max_retries = retry_cfg.max_retries;
|
||||||
if max_retries == 0 {
|
if max_retries == 0 {
|
||||||
@@ -131,7 +131,7 @@ impl Node {
|
|||||||
/// preserved and incremented rather than reset to zero. This ensures
|
/// preserved and incremented rather than reset to zero. This ensures
|
||||||
/// exponential backoff accumulates across repeated link-dead events instead
|
/// exponential backoff accumulates across repeated link-dead events instead
|
||||||
/// of resetting to the base interval on every peer removal.
|
/// of resetting to the base interval on every peer removal.
|
||||||
pub(super) fn schedule_reconnect(&mut self, node_addr: NodeAddr, now_ms: u64) {
|
pub(in crate::node) fn schedule_reconnect(&mut self, node_addr: NodeAddr, now_ms: u64) {
|
||||||
// Find peer in auto-connect config
|
// Find peer in auto-connect config
|
||||||
let peer_config = self
|
let peer_config = self
|
||||||
.config()
|
.config()
|
||||||
@@ -196,7 +196,7 @@ impl Node {
|
|||||||
/// entry stays in `retry_pending` until the connection succeeds (cleared
|
/// entry stays in `retry_pending` until the connection succeeds (cleared
|
||||||
/// in `promote_connection`) or max retries are exhausted (cleared in
|
/// in `promote_connection`) or max retries are exhausted (cleared in
|
||||||
/// `schedule_retry`).
|
/// `schedule_retry`).
|
||||||
pub(super) async fn process_pending_retries(&mut self, now_ms: u64) {
|
pub(in crate::node) async fn process_pending_retries(&mut self, now_ms: u64) {
|
||||||
if self.retry_pending.is_empty() {
|
if self.retry_pending.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -831,7 +831,7 @@ async fn test_process_pending_retries_is_budgeted_per_tick() {
|
|||||||
let node_addr = *peer_identity.node_addr();
|
let node_addr = *peer_identity.node_addr();
|
||||||
node.retry_pending.insert(
|
node.retry_pending.insert(
|
||||||
node_addr,
|
node_addr,
|
||||||
crate::node::retry::RetryState {
|
crate::node::peering::retry::RetryState {
|
||||||
peer_config: crate::config::PeerConfig::new(npub, "udp", "10.0.0.2:2121"),
|
peer_config: crate::config::PeerConfig::new(npub, "udp", "10.0.0.2:2121"),
|
||||||
retry_count: 0,
|
retry_count: 0,
|
||||||
retry_after_ms: 0,
|
retry_after_ms: 0,
|
||||||
@@ -1256,7 +1256,7 @@ async fn test_process_pending_retries_drops_expired_entries() {
|
|||||||
let peer_npub = peer_identity.npub();
|
let peer_npub = peer_identity.npub();
|
||||||
let peer_node_addr = *PeerIdentity::from_npub(&peer_npub).unwrap().node_addr();
|
let peer_node_addr = *PeerIdentity::from_npub(&peer_npub).unwrap().node_addr();
|
||||||
|
|
||||||
let mut state = super::super::retry::RetryState::new(crate::config::PeerConfig::new(
|
let mut state = super::super::peering::retry::RetryState::new(crate::config::PeerConfig::new(
|
||||||
peer_npub,
|
peer_npub,
|
||||||
"udp",
|
"udp",
|
||||||
"127.0.0.1:9",
|
"127.0.0.1:9",
|
||||||
@@ -1409,7 +1409,7 @@ fn test_promote_clears_retry_pending() {
|
|||||||
// Simulate a retry entry existing for this peer
|
// Simulate a retry entry existing for this peer
|
||||||
node.retry_pending.insert(
|
node.retry_pending.insert(
|
||||||
node_addr,
|
node_addr,
|
||||||
super::super::retry::RetryState::new(crate::config::PeerConfig::default()),
|
super::super::peering::retry::RetryState::new(crate::config::PeerConfig::default()),
|
||||||
);
|
);
|
||||||
assert_eq!(node.retry_pending.len(), 1);
|
assert_eq!(node.retry_pending.len(), 1);
|
||||||
|
|
||||||
@@ -1720,7 +1720,7 @@ async fn process_pending_retries_gated_at_capacity() {
|
|||||||
let peer_identity = Identity::generate();
|
let peer_identity = Identity::generate();
|
||||||
let peer_npub = peer_identity.npub();
|
let peer_npub = peer_identity.npub();
|
||||||
let peer_node_addr = *PeerIdentity::from_npub(&peer_npub).unwrap().node_addr();
|
let peer_node_addr = *PeerIdentity::from_npub(&peer_npub).unwrap().node_addr();
|
||||||
let mut state = super::super::retry::RetryState::new(crate::config::PeerConfig::new(
|
let mut state = super::super::peering::retry::RetryState::new(crate::config::PeerConfig::new(
|
||||||
peer_npub,
|
peer_npub,
|
||||||
"udp",
|
"udp",
|
||||||
"127.0.0.1:9",
|
"127.0.0.1:9",
|
||||||
|
|||||||
Reference in New Issue
Block a user