Skip to content

Edge::run never returns after its shutdown signal: the transport listen tasks have no shutdown path and run joins them #578

Description

@emooreatx

edge v21.0.0, found from CIRISServer#568 while making the node's stop legible.

Edge::run(shutdown_rx) (src/edge.rs ~4359) does this:

let mut tasks = Vec::new();
for transport in &self.transports {
    let t = transport.clone(); let tx = inbound_tx.clone();
    tasks.push(tokio::spawn(async move {
        if let Err(e) = t.listen(tx).await { tracing::error!(, "transport listen exited"); }
    }));
}loop { tokio::select! { _ = shutdown.changed() => { tracing::info!("edge: shutdown signal received"); break; }} }
for t in tasks { let _ = t.await; }
Ok(())

The outbound dispatcher and the blackhole pruner get shutdown_rx clones and stop (dispatcher: shutdown signal received is logged). The transport listen tasks get no shutdown receiver, ReticulumTransport::listen never returns on its own, and run then awaits them forever. So run logs "shutdown signal received" and never returns.

Measured on a standalone ciris-server 0.5.203 (SIGTERM at 16:07:35 UTC): read API drained in <1 ms, every server loop logged "shutting down", edge logged the two lines above at 16:07:35.1807 — and the process was alive with 38 threads eight minutes later, still admitting RNS announces (peer_admitted … 16:12:38) and ticking the trace-plane watch (16:15:04), until kill -9. In the mesh harness the same node ends docker stop with exit 137 after the 30 s grace. The server had been waiting on edge_join.await.

Ask: either hand the listener tasks the shutdown receiver (select! the listen future against shutdown.changed() and close the transport), or have run stop the transports (t.close()/shutdown()) before joining. Until then CIRISServer bounds the join (10 s, then abort(), named at ERROR) so a stop cannot hang on it — that is a mitigation, not the fix: an aborted listener does not close its sockets cleanly.

Repro without the harness: ciris-server --home <scratch>, wait for :4243/health 200, kill -TERM <pid>, watch it not exit.

🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions