mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-11 15:46:53 +00:00
3b6397012b
- Add READY atomic flag to track full initialization status - Implement initialize_safe and start_safe methods with mutex protection - Add wait_until_ready function with configurable timeout - Create initialize_and_start_with_ready_check helper method - Replace sleep-based waiting with proper readiness checks - Add safety checks before sending events - Replace chrono with std::time for time handling - Update error handling to provide clear initialization status This change reduces race conditions in multi-threaded environments and ensures events are only processed when the system is fully ready.
102 lines
3.5 KiB
Rust
102 lines
3.5 KiB
Rust
#[cfg(feature = "http-producer")]
|
|
pub use crate::producer::http::HttpProducer;
|
|
#[cfg(feature = "http-producer")]
|
|
pub use crate::producer::EventProducer;
|
|
|
|
#[cfg(feature = "http-producer")]
|
|
pub use crate::config::HttpProducerConfig;
|
|
use crate::{event_bus, ChannelAdapter, Error, Event, EventStore, NotificationConfig};
|
|
use std::sync::Arc;
|
|
use tokio::sync::mpsc;
|
|
use tokio_util::sync::CancellationToken;
|
|
|
|
/// The `NotificationSystem` struct represents the notification system.
|
|
/// It manages the event bus and the adapters.
|
|
/// It is responsible for sending and receiving events.
|
|
/// It also handles the shutdown process.
|
|
pub struct NotificationSystem {
|
|
tx: mpsc::Sender<Event>,
|
|
rx: Option<mpsc::Receiver<Event>>,
|
|
store: Arc<EventStore>,
|
|
shutdown: CancellationToken,
|
|
#[cfg(feature = "http-producer")]
|
|
http_config: HttpProducerConfig,
|
|
}
|
|
|
|
impl NotificationSystem {
|
|
/// Creates a new `NotificationSystem` instance.
|
|
pub async fn new(config: NotificationConfig) -> Result<Self, Error> {
|
|
let (tx, rx) = mpsc::channel::<Event>(config.channel_capacity);
|
|
let store = Arc::new(EventStore::new(&config.store_path).await?);
|
|
let shutdown = CancellationToken::new();
|
|
|
|
let restored_logs = store.load_logs().await?;
|
|
for log in restored_logs {
|
|
for event in log.records {
|
|
// For example, where the send method may return a SendError when calling it
|
|
tx.send(event).await.map_err(|e| Error::ChannelSend(Box::new(e)))?;
|
|
}
|
|
}
|
|
|
|
Ok(Self {
|
|
tx,
|
|
rx: Some(rx),
|
|
store,
|
|
shutdown,
|
|
#[cfg(feature = "http-producer")]
|
|
http_config: config.http,
|
|
})
|
|
}
|
|
|
|
/// Starts the notification system.
|
|
/// It initializes the event bus and the producer.
|
|
pub async fn start(&mut self, adapters: Vec<Arc<dyn ChannelAdapter>>) -> Result<(), Error> {
|
|
let rx = self.rx.take().ok_or_else(|| Error::EventBusStarted)?;
|
|
|
|
let shutdown_clone = self.shutdown.clone();
|
|
let store_clone = self.store.clone();
|
|
let bus_handle = tokio::spawn(async move {
|
|
if let Err(e) = event_bus(rx, adapters, store_clone, shutdown_clone).await {
|
|
tracing::error!("Event bus failed: {}", e);
|
|
}
|
|
});
|
|
|
|
#[cfg(feature = "http-producer")]
|
|
{
|
|
let producer = crate::producer::http::HttpProducer::new(self.tx.clone(), self.http_config.port);
|
|
producer.start().await?;
|
|
}
|
|
|
|
tokio::select! {
|
|
result = bus_handle => {
|
|
result.map_err(Error::JoinError)?;
|
|
Ok(())
|
|
},
|
|
_ = self.shutdown.cancelled() => {
|
|
tracing::info!("System shutdown triggered");
|
|
Ok(())
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Sends an event to the notification system.
|
|
/// This method is used to send events to the event bus.
|
|
pub async fn send_event(&self, event: Event) -> Result<(), Error> {
|
|
self.tx.send(event).await.map_err(|e| Error::ChannelSend(Box::new(e)))?;
|
|
Ok(())
|
|
}
|
|
|
|
/// Shuts down the notification system.
|
|
/// This method is used to cancel the event bus and producer tasks.
|
|
pub fn shutdown(&self) {
|
|
self.shutdown.cancel();
|
|
}
|
|
|
|
/// Sets the HTTP port for the notification system.
|
|
/// This method is used to change the port for the HTTP producer.
|
|
#[cfg(feature = "http-producer")]
|
|
pub fn set_http_port(&mut self, port: u16) {
|
|
self.http_config.port = port;
|
|
}
|
|
}
|