fix: log JoinErrors in reconnect_all; restore pub(crate) for EdgeConnectionsCacheEntry

- pool_config.rs: replace silent .is_some() drain with while-let that logs
  JoinError, making panics in reconnect tasks visible in production logs.
  Add tokio regression test verifying panicking tasks yield JoinError.
- runtime_edge.rs: revert EdgeConnectionsCacheEntry visibility from pub to
  pub(crate); the type is internal to the api module and must not be
  exported beyond crate scope.
- Copilot issues for dashed lint names, unreachable!/clippy::panic, and
  tokio::rename atomicity were confirmed false positives via empirical
  cargo clippy runs and POSIX semantics analysis.
This commit is contained in:
David Osipov 2026-03-14 23:04:44 +04:00
parent 3ec316fbcd
commit d7da0b3584
No known key found for this signature in database
GPG Key ID: 0E55C4A47454E82E
2 changed files with 25 additions and 2 deletions

View File

@ -67,7 +67,7 @@ pub(super) struct RuntimeEdgeConnectionsSummaryData {
}
#[derive(Clone)]
pub struct EdgeConnectionsCacheEntry {
pub(crate) struct EdgeConnectionsCacheEntry {
pub(super) expires_at: Instant,
pub(super) payload: RuntimeEdgeConnectionsSummaryPayload,
pub(super) generated_at_epoch_secs: u64,

View File

@ -147,7 +147,11 @@ impl MePool {
if spawned == 0 {
break;
}
while join.join_next().await.is_some() {}
while let Some(result) = join.join_next().await {
if let Err(err) = result {
warn!(error = ?err, "reconnect task failed (panic or cancellation)");
}
}
}
}
}
@ -202,6 +206,25 @@ mod tests {
);
}
// Regression: a panicking reconnect task must produce a catchable JoinError rather
// than being silently swallowed. If the while loop ever reverts to `.is_some()`
// the error is dropped; this test ensures the error EXISTS and can be observed.
#[tokio::test]
async fn panicking_reconnect_task_produces_join_error() {
let mut join: tokio::task::JoinSet<()> = tokio::task::JoinSet::new();
join.spawn(async { panic!("simulated reconnect task panic") });
let mut error_count = 0usize;
while let Some(result) = join.join_next().await {
if result.is_err() {
error_count += 1;
}
}
assert_eq!(
error_count, 1,
"exactly one JoinError must be emitted by the panicking task"
);
}
// Verify that the batch-iteration logic never exceeds MAX_CONCURRENT_RECONNECTS
// tasks per batch, regardless of how many writers exist.
#[test]