Summary
Multiple locations use tokio::spawn without collecting the JoinHandle, making it impossible to detect task panics or failures.
Problem Locations
crates/consensus/src/host.rs:884 - DCL cut processing task
crates/node/src/network.rs:106,112 - Network listener and connection handlers
crates/node/src/node.rs:276 - Peer connection retry task
Code Example
// crates/consensus/src/host.rs:882-890
// Spawn background task to process DCL cuts
let value_builder_for_cuts = Arc::clone(&value_builder);
tokio::spawn(async move { // JoinHandle is dropped immediately
while let Some(cut) = cut_rx.recv().await {
let height = ConsensusHeight::from(cut.height);
value_builder_for_cuts.store_cut(height, cut).await;
}
warn!("Host: DCL cut receiver closed");
});
Impact
- Silent Failures: If a spawned task panics, no error is reported
- Debugging Difficulty: No way to know if background tasks are running correctly
- Resource Leaks: Panic in spawned task may leave resources in inconsistent state
Recommended Fix
- Collect
JoinHandle in a Vec<JoinHandle<()>> or JoinSet
- Monitor handles for completion/panic in a supervisor task
- Use
tokio::select! to handle task failures gracefully
// Better pattern:
let mut join_set = JoinSet::new();
join_set.spawn(async move {
// task code
});
// Later, monitor for failures:
while let Some(result) = join_set.join_next().await {
if let Err(e) = result {
error!("Background task failed: {:?}", e);
}
}
Summary
Multiple locations use
tokio::spawnwithout collecting theJoinHandle, making it impossible to detect task panics or failures.Problem Locations
crates/consensus/src/host.rs:884- DCL cut processing taskcrates/node/src/network.rs:106,112- Network listener and connection handlerscrates/node/src/node.rs:276- Peer connection retry taskCode Example
Impact
Recommended Fix
JoinHandlein aVec<JoinHandle<()>>orJoinSettokio::select!to handle task failures gracefully