Skip to main content

litellm_rs/utils/event/
types.rs

1//! Event types and traits for the publish-subscribe system
2
3use std::fmt::Debug;
4use std::time::{SystemTime, UNIX_EPOCH};
5use tokio::sync::mpsc;
6use uuid::Uuid;
7
8/// Event type enumeration representing common CRUD operations
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10pub enum EventType {
11    /// Entity was created
12    Created,
13    /// Entity was updated
14    Updated,
15    /// Entity was deleted
16    Deleted,
17    /// Custom event type with a numeric identifier
18    Custom(u32),
19}
20
21impl EventType {
22    /// Returns true if this is a Created event
23    pub fn is_created(&self) -> bool {
24        matches!(self, EventType::Created)
25    }
26
27    /// Returns true if this is an Updated event
28    pub fn is_updated(&self) -> bool {
29        matches!(self, EventType::Updated)
30    }
31
32    /// Returns true if this is a Deleted event
33    pub fn is_deleted(&self) -> bool {
34        matches!(self, EventType::Deleted)
35    }
36
37    /// Returns true if this is a Custom event
38    pub fn is_custom(&self) -> bool {
39        matches!(self, EventType::Custom(_))
40    }
41
42    /// Returns the custom event code if this is a Custom event
43    pub fn custom_code(&self) -> Option<u32> {
44        match self {
45            EventType::Custom(code) => Some(*code),
46            _ => None,
47        }
48    }
49}
50
51impl std::fmt::Display for EventType {
52    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53        match self {
54            EventType::Created => write!(f, "Created"),
55            EventType::Updated => write!(f, "Updated"),
56            EventType::Deleted => write!(f, "Deleted"),
57            EventType::Custom(code) => write!(f, "Custom({})", code),
58        }
59    }
60}
61
62/// Generic event structure containing metadata and payload
63#[derive(Debug, Clone)]
64pub struct Event<T>
65where
66    T: Clone + Send + Sync,
67{
68    /// Unique event identifier
69    pub id: String,
70    /// Type of the event
71    pub event_type: EventType,
72    /// Event payload data
73    pub data: T,
74    /// Unix timestamp in milliseconds when the event was created
75    pub timestamp: u64,
76    /// Optional source identifier (e.g., component name)
77    pub source: Option<String>,
78    /// Optional correlation ID for tracing related events
79    pub correlation_id: Option<String>,
80}
81
82impl<T> Event<T>
83where
84    T: Clone + Send + Sync,
85{
86    /// Create a new event with the specified type and data
87    pub fn new(event_type: EventType, data: T) -> Self {
88        Self {
89            id: Uuid::new_v4().to_string(),
90            event_type,
91            data,
92            timestamp: current_timestamp_millis(),
93            source: None,
94            correlation_id: None,
95        }
96    }
97
98    /// Create a Created event
99    pub fn created(data: T) -> Self {
100        Self::new(EventType::Created, data)
101    }
102
103    /// Create an Updated event
104    pub fn updated(data: T) -> Self {
105        Self::new(EventType::Updated, data)
106    }
107
108    /// Create a Deleted event
109    pub fn deleted(data: T) -> Self {
110        Self::new(EventType::Deleted, data)
111    }
112
113    /// Create a Custom event with the specified code
114    pub fn custom(code: u32, data: T) -> Self {
115        Self::new(EventType::Custom(code), data)
116    }
117
118    /// Set the source of the event
119    pub fn with_source(mut self, source: impl Into<String>) -> Self {
120        self.source = Some(source.into());
121        self
122    }
123
124    /// Set the correlation ID for the event
125    pub fn with_correlation_id(mut self, correlation_id: impl Into<String>) -> Self {
126        self.correlation_id = Some(correlation_id.into());
127        self
128    }
129
130    /// Check if this event matches the specified type
131    pub fn is_type(&self, event_type: EventType) -> bool {
132        self.event_type == event_type
133    }
134}
135
136/// Subscriber trait for handling events
137///
138/// Implement this trait to create custom event handlers that can be
139/// registered with the EventBroker.
140#[async_trait::async_trait]
141pub trait Subscriber<T>: Send + Sync
142where
143    T: Clone + Send + Sync + 'static,
144{
145    /// Handle an incoming event
146    ///
147    /// This method is called for each event published to the broker.
148    /// Implementations should handle errors gracefully and not panic.
149    async fn on_event(&self, event: Event<T>);
150
151    /// Optional filter to determine if this subscriber should receive an event
152    ///
153    /// Return true to receive the event, false to skip it.
154    /// Default implementation returns true for all events.
155    fn should_receive(&self, event: &Event<T>) -> bool {
156        let _ = event;
157        true
158    }
159}
160
161/// Handle for managing a subscription
162///
163/// When dropped, the subscription is automatically cancelled.
164#[derive(Debug)]
165pub struct SubscriptionHandle {
166    /// Unique identifier for this subscription
167    pub id: String,
168    /// Flag indicating if the subscription is still active
169    active: std::sync::atomic::AtomicBool,
170}
171
172impl SubscriptionHandle {
173    /// Create a new subscription handle
174    pub fn new() -> Self {
175        Self {
176            id: Uuid::new_v4().to_string(),
177            active: std::sync::atomic::AtomicBool::new(true),
178        }
179    }
180
181    /// Check if the subscription is still active
182    pub fn is_active(&self) -> bool {
183        self.active.load(std::sync::atomic::Ordering::Relaxed)
184    }
185
186    /// Cancel the subscription
187    pub fn cancel(&self) {
188        self.active
189            .store(false, std::sync::atomic::Ordering::Relaxed);
190    }
191}
192
193impl Default for SubscriptionHandle {
194    fn default() -> Self {
195        Self::new()
196    }
197}
198
199/// Type alias for the event receiver channel
200pub type EventReceiver<T> = mpsc::Receiver<Event<T>>;
201
202/// Type alias for the event sender channel
203pub type EventSender<T> = mpsc::Sender<Event<T>>;
204
205/// Get current timestamp in milliseconds
206fn current_timestamp_millis() -> u64 {
207    SystemTime::now()
208        .duration_since(UNIX_EPOCH)
209        .unwrap_or_default()
210        .as_millis() as u64
211}