ClientManager

Struct ClientManager 

Source
pub struct ClientManager { /* private fields */ }
Expand description

Manages all connected WebSocket clients using lock-free DashMap.

Key design decisions:

  • Uses DashMap for lock-free concurrent access to client registry
  • Uses try_send instead of send to never block on slow clients
  • Disconnects clients that are backpressured (queue full) to prevent cascade failures
  • All public methods are non-blocking or use fine-grained per-key locks

Implementations§

Source§

impl ClientManager

Source

pub fn new() -> Self

Source

pub fn with_timeout(self, timeout: Duration) -> Self

Source

pub fn with_message_queue_size(self, queue_size: usize) -> Self

Source

pub fn add_client(&self, client_id: Uuid, ws_sender: WebSocketSender)

Add a new client connection.

Spawns a dedicated sender task for this client that reads from its mpsc channel and writes to the WebSocket. If the WebSocket write fails, the client is automatically removed from the registry.

Source

pub fn remove_client(&self, client_id: Uuid)

Remove a client from the registry.

Source

pub fn client_count(&self) -> usize

Get the current number of connected clients.

This is lock-free and returns an approximate count (may be slightly stale under high concurrency, which is fine for max_clients checks).

Source

pub fn send_to_client( &self, client_id: Uuid, data: Arc<Bytes>, ) -> Result<(), SendError>

Send data to a specific client (non-blocking).

This method NEVER blocks. If the client’s queue is full, the client is considered too slow and is disconnected to prevent cascade failures. Use this for live streaming updates.

For initial snapshots where you expect to send many messages at once, use send_to_client_async instead which will wait for queue space.

Source

pub async fn send_to_client_async( &self, client_id: Uuid, data: Arc<Bytes>, ) -> Result<(), SendError>

Send data to a specific client (async, waits for queue space).

This method will wait if the client’s queue is full, allowing the client time to catch up. Use this for initial snapshots where you need to send many messages at once.

For live streaming updates, use send_to_client instead which will disconnect slow clients rather than blocking.

Source

pub async fn send_compressed_async( &self, client_id: Uuid, payload: CompressedPayload, ) -> Result<(), SendError>

Send a potentially compressed payload to a client (async).

Compressed payloads are sent as binary frames (raw gzip). Uncompressed payloads are sent as text frames (JSON).

Source

pub fn update_subscription( &self, client_id: Uuid, subscription: Subscription, ) -> bool

Update the subscription for a client.

Source

pub fn update_client_last_seen(&self, client_id: Uuid)

Update the last_seen timestamp for a client.

Source

pub fn get_subscription(&self, client_id: Uuid) -> Option<Subscription>

Get the subscription for a client.

Source

pub fn has_client(&self, client_id: Uuid) -> bool

Check if a client exists.

Source

pub async fn add_client_subscription( &self, client_id: Uuid, sub_key: String, token: CancellationToken, ) -> bool

Source

pub async fn remove_client_subscription( &self, client_id: Uuid, sub_key: &str, ) -> bool

Source

pub async fn cancel_all_client_subscriptions(&self, client_id: Uuid)

Source

pub fn cleanup_stale_clients(&self) -> usize

Remove stale clients that haven’t been seen within the timeout period.

Source

pub fn start_cleanup_task(&self)

Start a background task that periodically cleans up stale clients.

Trait Implementations§

Source§

impl Clone for ClientManager

Source§

fn clone(&self) -> ClientManager

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Default for ClientManager

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more