use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Mutex;
use serde::Serialize;
#[derive(Default)]
pub struct ContextOsMetrics {
events_appended: AtomicU64,
events_broadcast: AtomicU64,
events_replayed: AtomicU64,
sse_connections_opened: AtomicU64,
sse_connections_closed: AtomicU64,
shared_sessions_loaded: AtomicU64,
shared_sessions_persisted: AtomicU64,
active_workspaces: Mutex<std::collections::HashSet<String>>,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct MetricsSnapshot {
pub events_appended: u64,
pub events_broadcast: u64,
pub events_replayed: u64,
pub sse_connections_active: u64,
pub sse_connections_total: u64,
pub shared_sessions_loaded: u64,
pub shared_sessions_persisted: u64,
pub active_workspace_count: usize,
}
impl ContextOsMetrics {
pub fn record_event_appended(&self) {
self.events_appended.fetch_add(1, Ordering::Relaxed);
}
pub fn record_event_broadcast(&self) {
self.events_broadcast.fetch_add(1, Ordering::Relaxed);
}
pub fn record_events_replayed(&self, count: u64) {
self.events_replayed.fetch_add(count, Ordering::Relaxed);
}
pub fn record_sse_connect(&self) {
self.sse_connections_opened.fetch_add(1, Ordering::Relaxed);
}
pub fn record_sse_disconnect(&self) {
self.sse_connections_closed.fetch_add(1, Ordering::Relaxed);
}
pub fn record_session_loaded(&self) {
self.shared_sessions_loaded.fetch_add(1, Ordering::Relaxed);
}
pub fn record_session_persisted(&self) {
self.shared_sessions_persisted
.fetch_add(1, Ordering::Relaxed);
}
pub fn record_workspace_active(&self, workspace_id: &str) {
if let Ok(mut set) = self.active_workspaces.lock() {
set.insert(workspace_id.to_string());
}
}
pub fn snapshot(&self) -> MetricsSnapshot {
let opened = self.sse_connections_opened.load(Ordering::Relaxed);
let closed = self.sse_connections_closed.load(Ordering::Relaxed);
MetricsSnapshot {
events_appended: self.events_appended.load(Ordering::Relaxed),
events_broadcast: self.events_broadcast.load(Ordering::Relaxed),
events_replayed: self.events_replayed.load(Ordering::Relaxed),
sse_connections_active: opened.saturating_sub(closed),
sse_connections_total: opened,
shared_sessions_loaded: self.shared_sessions_loaded.load(Ordering::Relaxed),
shared_sessions_persisted: self.shared_sessions_persisted.load(Ordering::Relaxed),
active_workspace_count: self.active_workspaces.lock().map_or(0, |s| s.len()),
}
}
}