From bb5614096f94d7e3ff7b2324af1c60c4e231d83f Mon Sep 17 00:00:00 2001 From: Porter Child Date: Thu, 24 Sep 2026 17:14:02 -0600 Subject: [PATCH] listener: honor the pump sleep rate SleepRate.next_sleep_time() built the next wake time from a hard-coded 0.01 rather than self.target_period, so the constructor argument was never read and every SleepRate was a fixed 100 Hz clock. Both callers pass 0.01, which is why it went unnoticed: the knob only fails once you try to turn it. Use target_period, and pump the listener loop at 0.25s instead of 0.01s. pump_all() was written to report whether it sent anything, since listener.py sleeps only when a pass sent nothing, but it returned None under a `-> True` annotation. Return the flag. This is what keeps bulk throughput independent of the pump period: a send refused by a congested channel is otherwise retried once per pump pass, so without it 0.25s costs ~55% of bulk throughput, while at 0.01s the flag changes nothing. A listener holding one idle session goes from 9.4% CPU and 99 wakeups/s to 1.2% and 14; a chatty session from 10.7% to 2.2%. Bulk is unchanged (3.5s for 274KB), and session close latency costs +0.18s on a path that already takes ~0.55s plus link RTT. 0.25s is the floor: the residue is CallbackSubprocess polling at 10Hz, and 0.5s measured the same latency for no further gain. --- rnsh/helpers.py | 2 +- rnsh/listener.py | 2 +- rnsh/session.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rnsh/helpers.py b/rnsh/helpers.py index 2fc757e..664799a 100644 --- a/rnsh/helpers.py +++ b/rnsh/helpers.py @@ -19,7 +19,7 @@ def __init__(self, target_period: float): def next_sleep_time(self) -> float: old_last_wake = self.last_wake self.last_wake = time.time() - next_wake = max(old_last_wake + 0.01, self.last_wake) + next_wake = max(old_last_wake + self.target_period, self.last_wake) sleep_for = next_wake - self.last_wake return sleep_for if sleep_for > 0 else 0 diff --git a/rnsh/listener.py b/rnsh/listener.py index 5299429..630e30b 100644 --- a/rnsh/listener.py +++ b/rnsh/listener.py @@ -225,7 +225,7 @@ def link_established(lnk: RNS.Link): _destination.announce() last_announce = time.time() - sleeper = helpers.SleepRate(0.01) + sleeper = helpers.SleepRate(0.25) try: while not await _check_finished(): diff --git a/rnsh/session.py b/rnsh/session.py index 4268a20..f64edec 100644 --- a/rnsh/session.py +++ b/rnsh/session.py @@ -192,13 +192,13 @@ def _initiator_identified(self, outlet, identity): self._set_state(LSState.LSSTATE_WAIT_VERS) @classmethod - async def pump_all(cls) -> True: + async def pump_all(cls) -> bool: processed_any = False for session in cls.sessions: processed = session.pump() processed_any = processed_any or processed await asyncio.sleep(0) - + return processed_any @classmethod async def terminate_all(cls, reason: str):