feat(node): retry a transport whose start failed, without restarting the node

- Retain a failed-but-restartable transport handle in Node::pending_transports
  instead of dropping it (Node::start() Err arm previously discarded it)
- Retry pending transports on the node's existing 1s maintenance tick with
  exponential backoff (1s base, 30s cap), never giving up
- Promote a retried transport through the same adopt_started_transport() path
  a first-try success uses, including the cfg(unix) UDP fd hand-off
- Only handles whose post-failure state reports can_start() are quarantined;
  UDP/TCP (which stay in Starting on start error) are dropped exactly as today
- Add MockBleIo::fail_next_listens() to model a radio that is not available
  yet, mirroring the field failure text
This commit is contained in:
Arjen
2026-08-05 10:32:57 +01:00
parent 7e5a056820
commit 8104849f09
5 changed files with 374 additions and 8 deletions
+9
View File
@@ -26,6 +26,7 @@ pub(crate) mod stats;
pub(crate) mod stats_history;
#[cfg(test)]
mod tests;
mod transport_restart;
mod tree;
pub(crate) mod wire;
@@ -336,6 +337,12 @@ pub struct Node {
// === Transports & Links ===
/// Active transports (owned by Node).
transports: HashMap<TransportId, TransportHandle>,
/// Transport handles that failed to start and are awaiting a retry
/// on the maintenance tick (see `transport_restart`).
///
/// Invisible to every data-plane path until a retry succeeds — only
/// promoted into `transports` once `start()` returns `Ok`.
pending_transports: Vec<transport_restart::PendingTransport>,
/// Per-transport kernel drop tracking for congestion detection.
transport_drops: HashMap<TransportId, TransportDropState>,
/// Active links.
@@ -671,6 +678,7 @@ impl Node {
coord_cache,
recent_requests: HashMap::new(),
transports: HashMap::new(),
pending_transports: Vec::new(),
transport_drops: HashMap::new(),
links: HashMap::new(),
addr_to_link: HashMap::new(),
@@ -834,6 +842,7 @@ impl Node {
coord_cache,
recent_requests: HashMap::new(),
transports: HashMap::new(),
pending_transports: Vec::new(),
transport_drops: HashMap::new(),
links: HashMap::new(),
addr_to_link: HashMap::new(),