use crate::Result;
use std::{any::TypeId, fmt::Debug};
use uuid::Uuid;
mod dashmap;
pub use dashmap::DashMapRegistry;
#[derive(Debug, Clone)]
pub struct SubscriptionEntry {
pub id: Uuid,
pub name: Option<String>,
pub active: bool,
pub events_processed: u64,
pub durable_name: Option<String>,
}
impl SubscriptionEntry {
pub fn new(id: Uuid) -> Self {
Self {
id,
name: None,
active: true,
events_processed: 0,
durable_name: None,
}
}
pub fn with_name(id: Uuid, name: impl Into<String>) -> Self {
Self {
id,
name: Some(name.into()),
active: true,
events_processed: 0,
durable_name: None,
}
}
pub fn with_durable_name(mut self, name: impl Into<String>) -> Self {
self.durable_name = Some(name.into());
self
}
}
pub trait EventRegistry: Send + Sync + Debug {
fn register(
&self,
event_type: TypeId,
type_name: &str,
subscription: SubscriptionEntry,
) -> Result<()>;
fn unregister(&self, subscription_id: Uuid) -> Result<()>;
fn get_subscriptions(&self, event_type: TypeId) -> Vec<SubscriptionEntry>;
fn get_subscription(&self, subscription_id: Uuid) -> Option<SubscriptionEntry>;
fn increment_processed(&self, subscription_id: Uuid);
fn deactivate(&self, subscription_id: Uuid) -> Result<()>;
fn total_subscriptions(&self) -> usize;
fn subscription_count(&self, event_type: TypeId) -> usize;
fn event_types(&self) -> Vec<TypeId>;
fn clear(&self);
fn get_type_id(&self, type_name: &str) -> Option<TypeId> {
let _ = type_name; None
}
fn ack_event(&self, _subscription_id: Uuid, _event_id: Uuid) {
}
}
#[derive(Debug, Clone, Default)]
pub struct RegistryStats {
pub event_types: usize,
pub total_subscriptions: usize,
pub active_subscriptions: usize,
pub inactive_subscriptions: usize,
}
pub trait RegistryStatistics: EventRegistry {
fn stats(&self) -> RegistryStats {
let event_types = self.event_types();
let mut total = 0;
let mut active = 0;
let mut inactive = 0;
for event_type in &event_types {
let subs = self.get_subscriptions(*event_type);
total += subs.len();
active += subs.iter().filter(|s| s.active).count();
inactive += subs.iter().filter(|s| !s.active).count();
}
RegistryStats {
event_types: event_types.len(),
total_subscriptions: total,
active_subscriptions: active,
inactive_subscriptions: inactive,
}
}
}
impl<T: EventRegistry> RegistryStatistics for T {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_subscription_entry() {
let id = Uuid::max();
let entry = SubscriptionEntry::new(id);
assert_eq!(entry.id, id);
assert!(entry.active);
assert_eq!(entry.events_processed, 0);
assert!(entry.name.is_none());
}
#[test]
fn test_subscription_entry_with_name() {
let id = Uuid::max();
let entry = SubscriptionEntry::with_name(id, "test-handler");
assert_eq!(entry.name, Some("test-handler".to_string()));
}
}