Rust में Event Bus और Observer पैटर्न: कोड के साथ गाइड
Event Bus (इवेंट बस) एक आर्किटेक्चरल पैटर्न है जो publish-subscribe (प्रकाशक-सब्सक्राइबर) सिद्धांत पर काम करता है। Rust में यह पैटर्न ढीले-युग्मित (loosely coupled) सिस्टम बनाने के लिए बहुत उपयोगी है, जहाँ कंपोनेंट एक-दूसरे को सीधे जाने बिना इवेंट के ज़रिए संवाद करते हैं। इस लेख में हम Observer पैटर्न का उपयोग करके अपना खुद का Event Bus बनाएंगे और Rust इकोसिस्टम के तैयार समाधानों पर भी नज़र डालेंगे।
Observer पैटर्न: बुनियादी बातें
Observer पैटर्न ऑब्जेक्ट्स के बीच "एक-से-अनेक" (one-to-many) संबंध को परिभाषित करता है। जब एक ऑब्जेक्ट (प्रकाशक) अपनी स्थिति बदलता है, तो सभी आश्रित ऑब्जेक्ट्स (सब्सक्राइबर) को स्वचालित रूप से सूचित किया जाता है। Rust में इसे अक्सर traits और डायनामिक डिस्पैच के ज़रिए लागू किया जाता है।
Rust में Observer की बुनियादी इम्प्लीमेंटेशन
use std::collections::HashMap;
// ऑब्ज़र्वर के लिए ट्रेट
trait Observer {
fn update(&self, event: &str);
}
// प्रकाशक की संरचना
struct EventManager {
observers: Vec<Box<dyn Observer>>,
}
impl EventManager {
fn new() -> Self {
EventManager {
observers: Vec::new(),
}
}
fn subscribe(&mut self, observer: Box<dyn Observer>) {
self.observers.push(observer);
}
fn notify(&self, event: &str) {
for observer in &self.observers {
observer.update(event);
}
}
}
// एक विशिष्ट ऑब्ज़र्वर
struct Logger;
impl Observer for Logger {
fn update(&self, event: &str) {
println!("[Logger] इवेंट प्राप्त हुआ: {}", event);
}
}
fn main() {
let mut manager = EventManager::new();
manager.subscribe(Box::new(Logger));
manager.notify("user.login");
}
Event Bus: Observer का विस्तारित संस्करण
Event Bus एक केंद्रीकृत बस है जो इवेंट को उनके प्रकार के अनुसार रूट करती है। साधारण Observer के विपरीत, यहाँ विभिन्न प्रकार के इवेंट और सब्सक्रिप्शन फ़िल्टरिंग का समर्थन किया जाता है।
इवेंट प्रकारों के साथ Event Bus की इम्प्लीमेंटेशन
use std::any::Any;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
// इवेंट का प्रकार
#[derive(Clone, Debug)]
enum EventType {
UserLogin,
UserLogout,
DataUpdate,
}
// इवेंट की संरचना
#[derive(Clone, Debug)]
struct Event {
event_type: EventType,
payload: String,
}
// इवेंट हैंडलर
type Handler = Arc<dyn Fn(Event) + Send + Sync>;
// इवेंट बस
struct EventBus {
handlers: HashMap<EventType, Vec<Handler>>,
}
impl EventBus {
fn new() -> Self {
EventBus {
handlers: HashMap::new(),
}
}
fn subscribe<F>(&mut self, event_type: EventType, handler: F)
where
F: Fn(Event) + 'static + Send + Sync,
{
self.handlers
.entry(event_type)
.or_insert_with(Vec::new)
.push(Arc::new(handler));
}
fn publish(&self, event: Event) {
if let Some(handlers) = self.handlers.get(&event.event_type) {
for handler in handlers {
handler(event.clone());
}
}
}
}
fn main() {
let mut bus = EventBus::new();
bus.subscribe(EventType::UserLogin, |event| {
println!("उपयोगकर्ता लॉगिन हुआ: {}", event.payload);
});
bus.subscribe(EventType::UserLogin, |event| {
// दूसरा हैंडलर
println!("लॉगिन दर्ज किया गया: {}", event.payload);
});
bus.publish(Event {
event_type: EventType::UserLogin,
payload: "user123".to_string(),
});
}
Tokio के साथ Async Event Bus
वास्तविक एप्लिकेशन में अक्सर इवेंट की एसिंक्रोनस प्रोसेसिंग की आवश्यकता होती है। इसके लिए tokio लाइब्रेरी अपने broadcast चैनलों के साथ बहुत उपयुक्त है।
tokio::sync::broadcast का उपयोग
use tokio::sync::broadcast;
#[tokio::main]
async fn main() {
// 16 संदेशों के बफर के साथ broadcast चैनल बनाएँ
let (tx, mut rx1) = broadcast::channel::<String>(16);
let mut rx पुस्तकालय में भी
TypeScript अनुप्रयोगों की निगरानी: लाइब्रेरी, उपकरण और कॉन्फ़िगरेशन
Kotlin Symbol Processing (KSP) गाइड: कोटलिन कोड जनरेशन का पूरा ट्यूटोरियल
C# (.NET) पर SMS भेजना: SMS सेवा API के साथ एकीकरण
Rust में PDF जनरेशन: लाइब्रेरी और टूल्स का अवलोकन