// Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only use async_trait::async_trait; use std::any; use std::any::Any; use std::time::Duration; use tokio::time::Instant; use tracing::trace; pub(crate) mod client_sessions; pub(crate) mod global_prometheus_updater; pub(crate) mod legacy_packet_data; pub(crate) mod mixnet_data_cleaner; pub(crate) mod pending_egress_packets_updater; pub(crate) mod prometheus_events_handler; pub(crate) trait RegistrableHandler: Downcast + OnStartMetricsHandler + OnUpdateMetricsHandler + Send + Sync + 'static { } impl RegistrableHandler for T where T: Downcast + OnStartMetricsHandler + OnUpdateMetricsHandler + Send + Sync + 'static { } pub trait Downcast { #[allow(dead_code)] fn as_any(&'_ self) -> &'_ dyn Any where Self: 'static; fn as_any_mut(&'_ mut self) -> &mut dyn Any where Self: 'static; } impl Downcast for T { fn as_any(&'_ self) -> &'_ dyn Any where Self: 'static, { self } fn as_any_mut(&'_ mut self) -> &'_ mut dyn Any where Self: 'static, { self } } #[async_trait] pub(crate) trait MetricsHandler: RegistrableHandler { type Events; async fn handle_event(&mut self, event: Self::Events); } #[async_trait] pub(crate) trait OnStartMetricsHandler { async fn on_start(&mut self) {} } #[async_trait] pub(crate) trait OnUpdateMetricsHandler { async fn on_update(&mut self) {} } pub(crate) struct HandlerWrapper { handler: Box>, update_interval: Option, last_updated: Instant, } impl HandlerWrapper { pub fn new(update_interval: impl Into>, handler: U) -> Self where U: MetricsHandler, { HandlerWrapper { handler: Box::new(handler), update_interval: update_interval.into(), last_updated: Instant::now(), } } } impl HandlerWrapper where T: 'static, { pub(crate) async fn handle_event(&mut self, event: T) { self.handler.handle_event(event).await } } #[async_trait] impl OnStartMetricsHandler for HandlerWrapper { async fn on_start(&mut self) { let name = any::type_name::(); trace!("on start for handler for events of type {name}"); self.handler.on_start().await; } } #[async_trait] impl OnUpdateMetricsHandler for HandlerWrapper { async fn on_update(&mut self) { let Some(update_interval) = self.update_interval else { return; }; let name = any::type_name::(); trace!("on update for handler for events of type {name}"); let elapsed = self.last_updated.elapsed(); if elapsed < update_interval { trace!("too soon for updates"); return; } self.handler.on_update().await; self.last_updated = Instant::now(); } }