services: report bound listener addresses - #991
Open
torinnd wants to merge 2 commits into
Open
Conversation
Add ListenerConfig::fd_transfer_id so listeners sharing a configured address, including repeated port-zero and SO_REUSEPORT listeners, use distinct fd-table keys and retain their sockets across same-version graceful upgrades. Fixed TCP, Unix, and unidentified listeners retain their existing keys. Validate IDs during listener construction and return BindError for empty, whitespace-containing, or duplicate IDs. Track keys registered by the current process so an unidentified duplicate address is a bind error rather than a second owner of the same raw fd; no upstream test or example relies on that sharing. Mixed-version upgrades may rebind identified listeners because old binaries do not understand the new keys. Tests cover build-time validation, distinct routing, duplicate IDs, legacy keys, and a real SCM_RIGHTS round trip.
Allow callers to subscribe to the actual addresses of a listening service before moving it into Server. The service publishes every bound TCP or Unix address after all listeners bind and before accept loops start. This makes full-server tests with port 0 race-free while Pingora retains ownership of listening fds. TCP port-0 listeners can use stable transfer IDs from the parent change to remain distinct and retain their ports across new-to-new graceful upgrades. The transfer-ID API documents that explicitly identified listeners may rebind during a mixed-version upgrade or rollback. Tests connect through published addresses and run two services with the same 127.0.0.1:0 configuration and distinct transfer IDs.
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 #988.
Today there is no way to learn the actual address of a listener bound to port 0 while
Serverowns the listening fds. Tests and embedders that want an OS-assigned port have to either give up graceful upgrade and bind the socket themselves, or poll.This PR adds
Service::watch_bound_addresses(), atokio::sync::watchreceiver. The service publishes every bound TCP and Unix address once, in endpoint insertion order, after all of its listeners bind and before any accept loop starts. Callers subscribe before moving the service intoServer. If startup fails, the watch closes without a value.To support this,
ListenerEndpoint::local_addrandTransportStack::local_addrare now crate-visible (they were#[cfg(test)]) and return the L4SocketAddrso Unix listeners are covered too. No changes to the accept path.Tests start a full
Serverwith a port-0 listener and connect through the published address, and run two services with the same127.0.0.1:0configuration and distinct transfer IDs to check they publish different ports and route correctly.(This is a two-commit PR, following #990. If #990 merges first, this PR rebases down to the second commit only.)