refactor(protocol): clarify pending_moves expiry sweep

The original mem::replace + retain pattern worked but was opaque.
Switch to a two-pass approach: collect expired MessageHandles into
a small Vec, then remove + resolve. Behaviour-preserving; the
clippy-style readability win is worth the tiny extra allocation
(typical case: 0 or 1 expired entries per loop iteration).
This commit is contained in:
EdisonJwa
2026-05-16 10:10:03 +08:00
parent 2511b24982
commit 01003b3448
+15 -15
View File
@@ -500,24 +500,24 @@ async fn connection_task(
// 2b. Sweep stale pending_moves whose deadline has passed. // 2b. Sweep stale pending_moves whose deadline has passed.
// The server should always reply within ~1 s; 3 s is a // The server should always reply within ~1 s; 3 s is a
// generous ceiling. Expired entries get an Ok() so the // generous ceiling. Expired entries fall back to Ok() so
// caller's snapshot-confirmation polling still has a chance // the caller's snapshot-confirmation polling still has a
// to detect success (fall back to the previous optimistic // chance to detect success — better than a fake
// behaviour rather than blocking the user with a fake // ServerRejected for legacy servers that never reply to
// ServerRejected). // move requests.
if !pending_moves.is_empty() { if !pending_moves.is_empty() {
let now = std::time::Instant::now(); let now = std::time::Instant::now();
pending_moves.retain(|_, (reply, deadline)| { let expired: Vec<MessageHandle> = pending_moves
if now >= *deadline { .iter()
// Cannot move `reply` out of `&mut` cleanly here .filter_map(|(handle, (_, deadline))| {
// without an intermediate take(); use a sentinel if now >= *deadline { Some(*handle) } else { None }
// sender so retain's signature works. })
let _ = std::mem::replace(reply, oneshot::channel().0).send(Ok(())); .collect();
false for handle in expired {
} else { if let Some((reply, _)) = pending_moves.remove(&handle) {
true let _ = reply.send(Ok(()));
} }
}); }
} }
// 3. Service at most one control request (non-blocking). // 3. Service at most one control request (non-blocking).