-
Notifications
You must be signed in to change notification settings - Fork 2
Closed
Description
Description
MeasureManyStream never returns None to signal stream completion. After all ping requests have been sent and all responses received, poll_next_unpin returns Poll::Pending forever instead of Poll::Ready(None).
This causes while let loops to hang indefinitely:
let mut stream = pinger.measure_many([localhost].into_iter());
// This hangs forever after receiving the ping response
while let Some((addr, rtt)) = stream.next().await {
println!("{addr}: {rtt:?}");
}
// Never reaches hereRoot Cause
In pinger.rs, poll_next_unpin has return type Poll<(V, Duration)> (no Option!) and always returns Poll::Pending at the end:
pub fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll<(V, Duration)> {
// ... process results ...
Poll::Pending // Always pending, never signals completion
}The Stream implementation then wraps everything in Some, so it can never return None:
fn poll_next(...) -> Poll<Option<Self::Item>> {
let result = ready!(self.poll_next_unpin(cx));
Poll::Ready(Some(result)) // Always Some!
}Expected Behavior
The stream should return None when:
- All addresses in
send_queuehave been sent - All entries in
in_flighthave received responses (or timed out)
Suggested Fix
- Change
poll_next_unpinreturn type toPoll<Option<(V, Duration)>> - Add completion check:
if send_queue.peek().is_none() && in_flight.is_empty() { return Poll::Ready(None); } - Update
Streamimpl to pass through theOptiondirectly - Same changes needed for
DualstackMeasureManyStream
Metadata
Metadata
Assignees
Labels
No labels