feat: 开放 Rust 补丁程序源代码和编译说明
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
use futures::future::BoxFuture;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
future::Future,
|
||||
sync::{Arc, LazyLock},
|
||||
};
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use crate::{base::AppError, services::connect::data::Event};
|
||||
|
||||
use super::task::TaskManager;
|
||||
|
||||
type EventCallback = Arc<dyn Fn(Event) -> BoxFuture<'static, Result<(), AppError>> + Send + Sync>;
|
||||
|
||||
pub struct EventBus {
|
||||
subscribers: Arc<Mutex<HashMap<String, Vec<EventCallback>>>>,
|
||||
}
|
||||
|
||||
static INSTANCE: LazyLock<EventBus> = LazyLock::new(EventBus::new);
|
||||
|
||||
impl EventBus {
|
||||
fn new() -> Self {
|
||||
EventBus {
|
||||
subscribers: Arc::new(Mutex::new(HashMap::new())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn instance() -> &'static Self {
|
||||
&INSTANCE
|
||||
}
|
||||
|
||||
pub async fn subscribe<F, Fut>(&self, event: &str, callback: F)
|
||||
where
|
||||
F: Fn(Event) -> Fut + Send + Sync + 'static,
|
||||
Fut: Future<Output = Result<(), AppError>> + Send + 'static,
|
||||
{
|
||||
let mut subscribers = self.subscribers.lock().await;
|
||||
subscribers
|
||||
.entry(event.to_string())
|
||||
.or_insert_with(Vec::new)
|
||||
.push(Arc::new(move |event| Box::pin(callback(event))));
|
||||
}
|
||||
|
||||
pub async fn unsubscribe(&self, event: &str) {
|
||||
self.subscribers.lock().await.remove(event);
|
||||
let tag = format!("EventBus-{}", event);
|
||||
TaskManager::instance().dispose(&tag).await;
|
||||
}
|
||||
|
||||
pub async fn publish(&self, event: Event) {
|
||||
let Some(callbacks) = self.get_callbacks(&event.event).await else {
|
||||
return;
|
||||
};
|
||||
for callback in callbacks {
|
||||
let event = event.clone();
|
||||
let _ = callback(event).await;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn publish_async(&self, event: Event) {
|
||||
let Some(callbacks) = self.get_callbacks(&event.event).await else {
|
||||
return;
|
||||
};
|
||||
let tag = format!("EventBus-{}", event.event);
|
||||
for callback in callbacks {
|
||||
let event = event.clone();
|
||||
let task = tokio::spawn(async move {
|
||||
let _ = callback(event).await;
|
||||
});
|
||||
TaskManager::instance().add(&tag, task).await;
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_callbacks(&self, event: &str) -> Option<Vec<EventCallback>> {
|
||||
let subscribers = self.subscribers.lock().await;
|
||||
match subscribers.get(event) {
|
||||
Some(callbacks) => Some(callbacks.clone()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user