use crate::envelope::EventEnvelope;
use crate::operational_journal::FileOperationalJournal;
use parking_lot::Mutex;
use std::sync::Arc;
#[derive(Debug, Default)]
pub struct EventBus {
events: Mutex<Vec<EventEnvelope>>,
journal: Mutex<Option<Arc<FileOperationalJournal>>>,
journal_error: Mutex<Option<String>>,
}
impl Clone for EventBus {
fn clone(&self) -> Self {
let guard = self.events.lock();
Self {
events: Mutex::new(guard.clone()),
journal: Mutex::new(self.journal.lock().clone()),
journal_error: Mutex::new(self.journal_error.lock().clone()),
}
}
}
impl EventBus {
pub fn new() -> Self {
Self::default()
}
pub fn attach_journal(&self, journal: Arc<FileOperationalJournal>) {
let mut events = journal.events();
if events.len() > 10_000 {
events.drain(..events.len() - 10_000);
}
*self.events.lock() = events;
*self.journal.lock() = Some(journal);
*self.journal_error.lock() = None;
}
pub fn durability_error(&self) -> Option<String> {
self.journal_error.lock().clone()
}
pub fn emit(&self, event: EventEnvelope) {
self.persist(&event);
let mut guard = self.events.lock();
if guard.len() >= 10000 {
let to_remove = guard.len().saturating_sub(9999);
if to_remove > 0 {
guard.drain(0..to_remove);
}
}
guard.push(event);
}
pub fn emit_many(&self, events: Vec<EventEnvelope>) {
for event in &events {
self.persist(event);
}
let mut guard = self.events.lock();
guard.extend(events);
if guard.len() > 10000 {
let to_remove = guard.len().saturating_sub(10000);
if to_remove > 0 {
guard.drain(0..to_remove);
}
}
}
pub fn len(&self) -> usize {
self.events.lock().len()
}
pub fn is_empty(&self) -> bool {
self.events.lock().is_empty()
}
pub fn events(&self) -> Vec<EventEnvelope> {
self.events.lock().clone()
}
pub fn clear(&self) {
self.events.lock().clear();
}
fn persist(&self, event: &EventEnvelope) {
if let Some(journal) = self.journal.lock().clone() {
if let Err(error) = journal.append_event(event.clone()) {
*self.journal_error.lock() = Some(crate::redact_text(&format!("{error:?}")));
}
}
}
}
#[cfg(test)]
#[path = "event_bus_tests.rs"]
mod tests;