decipherhub / decipherhub/cipherbft
Fire-and-forget tokio::spawn pattern lacks panic detection
- Dominant language
- Rust
- Stars
- 9
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
## 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
```rust
// 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
1. Collect `JoinHandle` in a `Vec>` or `JoinSet`
2. Monitor handles for completion/panic in a supervisor task
3. Use `tokio::select!` to handle task failures gracefully
```rust
// 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);
}
}
```
Contributor guide
Assessment
This issue has not been assessed yet.