pub enum InheritedSocketFate {
Adopted,
Refused,
Unclaimed,
}Expand description
What a proxy would do with a listening socket handed to its
activate_listener(address).
Server::notify_activate_listener asks BEFORE it pulls a descriptor out of
the SCM table, because Listeners::get_* removes the entry as it hands it
over while activate() returns on its if self.active guard without
consuming anything. Taking a descriptor that nothing will consume drops the
owning wrapper on the floor and closes the inherited socket unused — the
accept backlog or receive buffer with it (sozu#1342).
Variants§
Adopted
A listener exists at the address and is not active: it adopts the socket. Take the descriptor.
Refused
A listener exists at the address and is already active on a socket of
its own. activate() short-circuits, so nothing consumes this
descriptor now. Close it deliberately.
Not because it could never be adopted: give_back_listener clears
active and keeps the listener object, so DeactivateListener followed
by ActivateListener — an operator-reachable feature, covered by
e2e/src/tests/listener_reactivation_tests.rs — brings this address back
to Adopted. Closing here is therefore irreversible:
scm_listeners is filled once in Server::new and never refilled, so a
reactivation after this point binds a fresh socket.
It is a deliberate trade, not a claim about the lifetime. The only thing
this descriptor carries is the connections queued on it at hand-off, and
their value decays — the peers behind them time out or reset while the
address is served by the listener’s own socket. The cost of keeping it is
continuous instead: the descriptor is the retiring worker’s listening
socket, still bound with SO_REUSEPORT and registered with no event
loop, so the kernel is expected to keep giving it a share of incoming
connections that nobody accepts. (That last step follows from
SO_REUSEPORT load-balancing semantics; nothing here measures it.) A
decaying backlog is not worth an indefinite share of new connections.
Unclaimed
No listener at the address yet. Keep the descriptor in the table: an
AddListener + ActivateListener pair can still arrive and adopt it,
which is exactly what an upgrade does when the initial state carries the
listeners inactive and activates them afterwards.
Trait Implementations§
Source§impl Clone for InheritedSocketFate
impl Clone for InheritedSocketFate
impl Copy for InheritedSocketFate
Source§impl Debug for InheritedSocketFate
impl Debug for InheritedSocketFate
impl Eq for InheritedSocketFate
Source§impl PartialEq for InheritedSocketFate
impl PartialEq for InheritedSocketFate
impl StructuralPartialEq for InheritedSocketFate
Auto Trait Implementations§
impl Freeze for InheritedSocketFate
impl RefUnwindSafe for InheritedSocketFate
impl Send for InheritedSocketFate
impl Sync for InheritedSocketFate
impl Unpin for InheritedSocketFate
impl UnsafeUnpin for InheritedSocketFate
impl UnwindSafe for InheritedSocketFate
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.