pub struct MaxConnListener<L> { /* private fields */ }Expand description
Wrap any axum::serve::Listener with a hard cap on concurrent
connections.
axum::serve exposes no connection cap of its own, so the limit lives here
as a listener adapter. Each accepted connection holds one permit for its
whole lifetime; the permit releases when the connection IO is dropped. When
the permits are exhausted, accept waits before pulling the next connection
off the OS queue, which back-pressures the accept loop instead of
unbounded-buffering new sockets. The permit semaphore is never closed, so a
drain does not revoke the permits of connections that are still finishing.
This wrapper changes the listener’s accepted IO type, which moves it out of
axum’s built-in Connected<_> for SocketAddr impl (that impl is bound to the
concrete TcpListener, and coherence forbids re-adding one for the foreign
SocketAddr). A site that still needs the peer address serves
into_make_service_with_connect_info::<CappedPeerAddr>() and reads
ConnectInfo<CappedPeerAddr>, so it keeps both the accept cap and connect
info.
Implementations§
Source§impl<L> MaxConnListener<L>
impl<L> MaxConnListener<L>
Sourcepub fn new(inner: L, max_connections: usize) -> Self
pub fn new(inner: L, max_connections: usize) -> Self
Cap inner at max_connections simultaneously accepted connections.
usize::MAX is a valid “effectively uncapped” sentinel: the count is
clamped to Semaphore::MAX_PERMITS so a large value is a no-op cap
rather than a startup panic.