fix(netwatch): mark the socket broken when a rebind fails, so sends retry it - #201
Open
jgeluk wants to merge 1 commit into
Open
fix(netwatch): mark the socket broken when a rebind fails, so sends retry it#201jgeluk wants to merge 1 commit into
jgeluk wants to merge 1 commit into
Conversation
…etry it
SocketState::rebind deliberately stays in Closed on a bind failure
('will retry on next attempt'), but nothing armed that retry:
UdpSocket::rebind propagated the error without setting is_broken, and
maybe_rebind — the only recovery path on the send/recv side — is gated
on is_broken. A single failed rebind (typically during sleep->wake,
when the network-change handler fires before interfaces are back up)
therefore stranded the socket in Closed permanently: every subsequent
send logged 'socket closed' at WARN and failed with BrokenPipe, at the
caller's full send rate, until the process restarted.
Mark the socket broken when the rebind fails, so the next send/recv
retries the bind and the socket heals as soon as the address is
bindable again. A deliberate close() still stays closed: it never sets
is_broken, pinned by a new test.
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.
Fixes #200.
Problem
SocketState::rebind()deliberately stays inClosedon a bind failure ("will retry on next attempt"), but nothing arms that retry:UdpSocket::rebind()propagates the error without settingis_broken, andmaybe_rebind()— the only recovery path on the send/recv side — is gated onis_broken. A single failed rebind (typically during sleep→wake on macOS, when the network-change handler fires before interfaces are back up) strands the socket inClosedpermanently: every subsequent send logssocket closedat WARN and fails withBrokenPipe, at the caller's full send rate, until the process restarts.Fix
Mark the socket broken when the rebind fails, so the next send/recv retries the bind and the socket heals as soon as the address is bindable again. A deliberate
close()still stays closed: it never setsis_broken, pinned by a new test.Tests
test_failed_rebind_marks_broken_so_sends_retry— forces a rebind failure, asserts the socket self-heals on the next send once the address is bindable again.test_deliberate_close_stays_closed— pins thatclose()remains terminal.cargo test -p netwatch --lib: 18 passed.Field-tested for several days across daemons that previously exhibited the storm: sleep/wake now recovers within a second, zero
socket closedevents.🤖 Generated with Claude Code