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}