pub struct DashboardServer { /* private fields */ }Expand description
SSE streaming dashboard server.
Pushes DashboardEvents to all connected HTTP clients that opened
GET /events. Events are first written to an internal
LockFreeRingBuffer and then forwarded to each client through a
tokio::sync::broadcast channel.
§Thread safety
The server is Send + Sync. push_event may be called from any thread
or async task.
Implementations§
Source§impl DashboardServer
impl DashboardServer
Sourcepub fn new(config: DashboardConfig) -> Result<Self>
pub fn new(config: DashboardConfig) -> Result<Self>
Creates a new server but does not start listening yet.
Call start to begin accepting connections.
§Errors
Returns an error if event_buffer_size is 0.
§Example
use trustformers_debug::dashboard_ws::websocket::{DashboardConfig, DashboardServer};
let cfg = DashboardConfig {
bind_addr: "127.0.0.1:0".parse().unwrap(),
max_clients: 4,
event_buffer_size: 32,
};
let server = DashboardServer::new(cfg).unwrap();
assert!(!server.is_running());Sourcepub fn is_running(&self) -> bool
pub fn is_running(&self) -> bool
Returns true if start has been called.
Sourcepub fn push_event(&self, event: DashboardEvent) -> Result<()>
pub fn push_event(&self, event: DashboardEvent) -> Result<()>
Pushes a DashboardEvent to all connected clients.
The event is serialised to JSON and written to the internal ring buffer as a sequence of bytes (the SSE-framed JSON string length is stored as an index rather than raw bytes — see implementation notes).
If no clients are connected the broadcast send silently drops the message (all receivers have been dropped), which is acceptable behaviour for a monitoring stream.
§Errors
Returns an error if JSON serialisation fails.
§Example
server.push_event(DashboardEvent::Custom {
name: "epoch_end".to_string(),
value: serde_json::json!({"epoch": 1}),
}).unwrap();Sourcepub async fn start(&self) -> Result<()>
pub async fn start(&self) -> Result<()>
Starts the SSE server in a background tokio task.
The method binds the TCP listener immediately (so binding errors are returned synchronously) and then spawns a task to accept connections.
§Errors
Returns an error if the TCP listener cannot bind to
config.bind_addr.
§Example
use trustformers_debug::dashboard_ws::websocket::{DashboardConfig, DashboardServer};
let cfg = DashboardConfig {
bind_addr: "127.0.0.1:0".parse()?,
max_clients: 2,
event_buffer_size: 16,
};
let server = DashboardServer::new(cfg)?;
server.start().await?;Auto Trait Implementations§
impl !RefUnwindSafe for DashboardServer
impl !UnwindSafe for DashboardServer
impl Freeze for DashboardServer
impl Send for DashboardServer
impl Sync for DashboardServer
impl Unpin for DashboardServer
impl UnsafeUnpin for DashboardServer
Blanket Implementations§
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> 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> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.