From 283bf8271f69f87a21edaea41a92965d7432b9fe Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 4 Apr 2024 12:33:09 +1100 Subject: [PATCH] fix(relay): don't busy-loop on `poll_timeout` (#4497) The value returned from `poll_timeout` needs to only reset the `Sleep` but don't need to go back to the top of the loop. Instead, we move its polling to below the resetting of `Sleep`. This will correctly register a waker in case we did change `Sleep`. This `continue` causes a busy-loop and stops the relay from dealing with the `phoenix-channel` which means the portal will eventually consider it offline. This was first introduced in #4455. --- rust/relay/src/main.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/rust/relay/src/main.rs b/rust/relay/src/main.rs index 2524a494d..a66ec3d33 100644 --- a/rust/relay/src/main.rs +++ b/rust/relay/src/main.rs @@ -433,13 +433,7 @@ where continue; // Attempt to process more commands. } - // Priority 2: Handle time-sensitive tasks: - if self.sleep.poll_unpin(cx).is_ready() { - self.server.handle_timeout(now); - continue; // Handle potentially new commands. - } - - // Priority 3: Handle relayed data (we prioritize latency for existing allocations over making new ones) + // Priority 2: Handle relayed data (we prioritize latency for existing allocations over making new ones) if let Poll::Ready(Some((data, sender, allocation))) = self.relay_data_receiver.poll_next_unpin(cx) { @@ -447,7 +441,7 @@ where continue; // Handle potentially new commands. } - // Priority 4: Accept new allocations / answer STUN requests etc + // Priority 3: Accept new allocations / answer STUN requests etc if let Poll::Ready(Some((buffer, sender))) = self.inbound_data_receiver.poll_next_unpin(cx) { @@ -455,10 +449,16 @@ where continue; // Handle potentially new commands. } - // Priority 5: Check when we need to next be woken. This needs to happen after all state modifications. + // Priority 4: Check when we need to next be woken. This needs to happen after all state modifications. if let Some(timeout) = self.server.poll_timeout() { Pin::new(&mut self.sleep).reset(timeout); - continue; + // Purposely no `continue` because we just change the state of `sleep` and we poll it below. + } + + // Priority 5: Handle time-sensitive tasks: + if self.sleep.poll_unpin(cx).is_ready() { + self.server.handle_timeout(now); + continue; // Handle potentially new commands. } // Priority 6: Handle portal messages