use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use std::ops::Deref;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_futures;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DiagEvent {
pub subsystem: &'static str,
pub stream_id: Option<String>,
pub ts_ms: u64,
pub metrics: Vec<Metric>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Metric {
pub name: &'static str,
pub value: MetricValue,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(tag = "t", content = "v")]
pub enum MetricValue {
I64(i64),
U64(u64),
F64(f64),
Text(String),
}
use async_broadcast::{broadcast, Receiver, Sender};
static SENDER: Lazy<Sender<DiagEvent>> = Lazy::new(|| {
let (s, r) = broadcast(256);
#[cfg(target_arch = "wasm32")]
{
let mut receiver = r;
wasm_bindgen_futures::spawn_local(async move {
while let Ok(_) = receiver.recv().await {
}
});
}
#[cfg(not(target_arch = "wasm32"))]
{
std::mem::drop(r);
}
s
});
pub fn global_sender() -> Sender<DiagEvent> {
SENDER.deref().clone()
}
pub fn subscribe() -> Receiver<DiagEvent> {
SENDER.deref().new_receiver()
}
#[cfg(not(target_arch = "wasm32"))]
pub fn now_ms() -> u64 {
use std::time::{SystemTime, UNIX_EPOCH};
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_millis() as u64
}
#[cfg(target_arch = "wasm32")]
pub fn now_ms() -> u64 {
js_sys::Date::now() as u64
}
#[macro_export]
macro_rules! metric {
($name:expr, $value:expr) => {
$crate::Metric {
name: $name,
value: $crate::MetricValue::from($value),
}
};
}
impl From<i64> for MetricValue {
fn from(v: i64) -> Self {
MetricValue::I64(v)
}
}
impl From<u64> for MetricValue {
fn from(v: u64) -> Self {
MetricValue::U64(v)
}
}
impl From<f64> for MetricValue {
fn from(v: f64) -> Self {
MetricValue::F64(v)
}
}
impl From<&str> for MetricValue {
fn from(v: &str) -> Self {
MetricValue::Text(v.to_string())
}
}
impl From<String> for MetricValue {
fn from(v: String) -> Self {
MetricValue::Text(v)
}
}