refactor(networking): event-driven wakeups, drop running-flag polling#743
Merged
tcoratger merged 1 commit intoMay 21, 2026
Merged
Conversation
LiveNetworkEventSource.__anext__ polled the running flag every 500ms via asyncio.wait_for + TimeoutError + continue. Add a stop event, set it on stop() and clear it on dial()/listen(), then race the queue against the stop event. Stop is now observed with no latency instead of up to half a second. GossipsubBehavior.get_next_event already raced an event, but the implementation manually cancelled and awaited each pending task and swallowed cancellation in a duplicate handler. Collapse to a single try/finally cancel pattern. Cancellation now propagates naturally, which the sole caller (_forward_gossipsub_events) already handles with its own except asyncio.CancelledError block. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related cleanups to async wakeup patterns in the networking subspec.
client/event_source/live.py— real fix (was polling)__anext__polled the running flag every 500ms viaasyncio.wait_for(..., timeout=0.5)+TimeoutError+continue. Replaced with a singleasyncio.wait(..., FIRST_COMPLETED)race between the event queue and a new_stop_event: asyncio.Eventfield. Stop is now observed with no latency instead of up to 500ms._stop_eventfield.dial()andlisten()call_stop_event.clear()next to each_running = Trueso restart still works.stop()calls_stop_event.set()next to_running = Falseso any waiter wakes immediately.gossipsub/behavior.py— cleanup, not bug fixget_next_eventalready raced the queue against a stop event, but the body manually cancelled and awaited each pending task and duplicated the cancellation handling in an outerexceptblock. Collapsed to a single try/finally cancel pattern (~46 lines → ~24 lines).Behavioural note: the original swallowed
asyncio.CancelledErrorand returnedNone. The new version lets cancellation propagate (the asyncio convention). The sole caller (_forward_gossipsub_eventsinlive.py:387) wraps the call inexcept asyncio.CancelledError: pass, so it already handles propagation correctly.Test plan
ruff check— clean on both files.uv run pytest tests/lean_spec/subspecs/networking/client/test_event_source.py tests/lean_spec/subspecs/networking/gossipsub/— 215 tests pass.🤖 Generated with Claude Code