pub struct ConnectionRegistry { /* private fields */ }Expand description
Sharded, lock-free-on-the-hot-path connection registry.
One instance is created at launch, leaked to &'static, and shared by every
gateway route. All mutating operations are O(1) amortised and touch only a
single shard; broadcast is O(connections) with no global lock.
Implementations§
Source§impl ConnectionRegistry
impl ConnectionRegistry
pub fn new() -> Self
Sourcepub fn register(
&self,
tx: Sender<WsMessage>,
claims: Option<Arc<Claims>>,
) -> ConnId
pub fn register( &self, tx: Sender<WsMessage>, claims: Option<Arc<Claims>>, ) -> ConnId
Register a freshly-upgraded socket. Returns its assigned ConnId.
tx must be the sending half of a bounded channel — the queue
depth is the slow-client memory ceiling (LaunchConfig::ws_outbound_buffer).
Sourcepub fn touch(&self, id: ConnId)
pub fn touch(&self, id: ConnId)
Record inbound activity for the idle sweeper. Called by the reader on every frame (including pongs); one relaxed store.
Sourcepub fn close_all(&self) -> usize
pub fn close_all(&self) -> usize
Send a Close frame to every live socket. Used by graceful
shutdown: WS connections otherwise keep axum’s drain phase open
indefinitely (until clients disconnect or the supervisor SIGKILLs),
which would mean plugin on_shutdown hooks never run in production.
Each socket’s writer task sends the frame and exits; readers follow.
Sourcepub fn sweep_idle(&self, max_idle_secs: u64) -> Vec<ConnId> ⓘ
pub fn sweep_idle(&self, max_idle_secs: u64) -> Vec<ConnId> ⓘ
Close connections with no inbound activity for max_idle_secs.
Dead TCP links (NAT timeouts, vanished mobile clients) never send a
Close frame — without reaping they linger in the registry forever,
eating queue memory on every broadcast. Returns the ids reaped.
Pair with a server ping (ws_ping_interval): pings provoke pongs,
pongs touch last_seen, so only truly dead links exceed the window.
Sourcepub fn unregister(&self, id: ConnId)
pub fn unregister(&self, id: ConnId)
Remove a socket and evict it from every room it had joined.
Sourcepub fn connection_count(&self) -> usize
pub fn connection_count(&self) -> usize
Number of live connections. O(1).
Sourcepub fn join_room(&self, id: ConnId, room: String)
pub fn join_room(&self, id: ConnId, room: String)
Add a connection to a room (Socket.IO-style logical channel).
§TOCTOU safety
Both member_rooms and rooms are updated while holding the DashMap
shard read-lock on conns (the Ref keeps the shard locked until it is
dropped). This prevents a concurrent unregister() — which needs the
shard write-lock — from removing the entry between the two writes,
which would otherwise leave a stale ConnId in rooms forever.
Sourcepub fn leave_room(&self, id: ConnId, room: &str)
pub fn leave_room(&self, id: ConnId, room: &str)
Remove a connection from a room.
Mirrors join_room’s lock order: hold the conns shard read-lock first
so a concurrent unregister() (which needs the write-lock) cannot remove
the entry between the two writes and leave a stale id in rooms.
Sourcepub fn send_text(&self, id: ConnId, text: Arc<str>)
pub fn send_text(&self, id: ConnId, text: Arc<str>)
Enqueue a text frame to one connection. Non-blocking; a full queue evicts the slow client, a dead receiver is dropped silently.
Sourcepub fn broadcast_text(&self, text: &str)
pub fn broadcast_text(&self, text: &str)
Fan a text frame out to every live connection. Creates one Arc<str>
allocation then enqueues N pointer copies — no per-connection memcpy.
Clients whose queues are full are evicted after the sweep
(removal inside iteration would deadlock the DashMap shard).
Sourcepub fn broadcast_room_text(&self, room: &str, text: &str)
pub fn broadcast_room_text(&self, room: &str, text: &str)
Fan a text frame out to the members of one room.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for ConnectionRegistry
impl !RefUnwindSafe for ConnectionRegistry
impl Send for ConnectionRegistry
impl Sync for ConnectionRegistry
impl Unpin for ConnectionRegistry
impl UnsafeUnpin for ConnectionRegistry
impl UnwindSafe for ConnectionRegistry
Blanket Implementations§
Source§impl<T> AggregateExpressionMethods for T
impl<T> AggregateExpressionMethods for T
Source§fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
DISTINCT modifier for aggregate functions Read moreSource§fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
ALL modifier for aggregate functions Read moreSource§fn aggregate_filter<P>(self, f: P) -> Self::Output
fn aggregate_filter<P>(self, f: P) -> Self::Output
Source§fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
Source§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::RequestSource§impl<T> IntoSql for T
impl<T> IntoSql for T
Source§fn into_sql<T>(self) -> Self::Expression
fn into_sql<T>(self) -> Self::Expression
self to an expression for Diesel’s query builder. Read moreSource§fn as_sql<'a, T>(&'a self) -> <&'a Self as AsExpression<T>>::Expression
fn as_sql<'a, T>(&'a self) -> <&'a Self as AsExpression<T>>::Expression
&self to an expression for Diesel’s query builder. Read more