Skip to main content

mcpr_core/event/
sink.rs

1//! `EventSink` trait — how consumers plug into the event bus.
2
3use super::types::ProxyEvent;
4
5/// A sink that consumes proxy events from the event bus.
6///
7/// Register sinks via [`EventManager`](super::EventManager). The event bus
8/// calls `on_event` for every event, and sinks filter by variant. Example:
9///
10/// ```rust,ignore
11/// impl EventSink for PrometheusSink {
12///     fn on_event(&self, event: &ProxyEvent) {
13///         if let ProxyEvent::Request(e) = event {
14///             self.request_counter.inc();
15///             self.latency_histogram.observe(e.latency_us as f64);
16///         }
17///     }
18///     fn name(&self) -> &'static str { "prometheus" }
19/// }
20/// ```
21///
22/// # Contract
23///
24/// - **`on_event` must not block.** If the sink needs I/O (HTTP, disk),
25///   buffer internally and flush in `flush()` or a background thread.
26/// - **`on_batch`** is called when multiple events are available. Override
27///   for sinks that benefit from batching (SQL INSERT, HTTP POST).
28/// - **`flush`** is called periodically (~5s) and on graceful shutdown.
29pub trait EventSink: Send + Sync {
30    /// Process a single event. Must not block.
31    fn on_event(&self, event: &ProxyEvent);
32
33    /// Process a batch of events. Default calls `on_event` for each.
34    fn on_batch(&self, events: &[ProxyEvent]) {
35        for event in events {
36            self.on_event(event);
37        }
38    }
39
40    /// Flush internal buffers to their destination.
41    fn flush(&self) {}
42
43    /// Human-readable sink name (for logging and debugging).
44    fn name(&self) -> &'static str;
45}
46
47/// A no-op sink that discards all events. Used when no sinks are configured.
48pub struct NoopSink;
49
50impl EventSink for NoopSink {
51    fn on_event(&self, _event: &ProxyEvent) {}
52    fn name(&self) -> &'static str {
53        "noop"
54    }
55}