انتقل إلى المحتوى الرئيسي
الهندسةMar 28, 2026

Deep EVM #21: البنية القائمة على الأحداث في Rust — نمط الحافلة للأنظمة الفورية

OS
Open Soft Team

Engineering Team

لماذا البنية القائمة على الأحداث

في الأنظمة الفورية عالية الإنتاجية — روبوتات MEV، خوادم API، خطوط معالجة البيانات — يجب أن تكون المكونات مفصولة ومستقلة. البنية القائمة على الأحداث تحقق هذا عبر نمط الحافلة.

نمط الحافلة (Event Bus)

use tokio::sync::broadcast;

#[derive(Clone, Debug)]
enum Event {
    NewBlock(BlockInfo),
    PendingTx(Transaction),
    ArbitrageFound(Opportunity),
    ProfitRealized(U256),
}

struct EventBus {
    sender: broadcast::Sender<Event>,
}

impl EventBus {
    fn new(capacity: usize) -> Self {
        let (sender, _) = broadcast::channel(capacity);
        Self { sender }
    }
    
    fn publish(&self, event: Event) {
        let _ = self.sender.send(event);
    }
    
    fn subscribe(&self) -> broadcast::Receiver<Event> {
        self.sender.subscribe()
    }
}

المنتجون والمستهلكون

// منتج: يراقب الكتل الجديدة
async fn block_monitor(provider: &Provider, bus: &EventBus) {
    let mut stream = provider.subscribe_blocks().await?;
    while let Some(block) = stream.next().await {
        bus.publish(Event::NewBlock(block.into()));
    }
}

// مستهلك: يبحث عن فرص مراجحة
async fn arb_searcher(bus: &EventBus, graph: &Graph) {
    let mut rx = bus.subscribe();
    while let Ok(event) = rx.recv().await {
        if let Event::NewBlock(block) = event {
            let opportunities = find_arbitrage(graph, &block).await;
            for opp in opportunities {
                bus.publish(Event::ArbitrageFound(opp));
            }
        }
    }
}

التعامل مع الضغط الخلفي

عندما يكون المستهلك أبطأ من المنتج:

use tokio::sync::mpsc;

// قناة محدودة الحجم للضغط الخلفي
let (tx, mut rx) = mpsc::channel::<Event>(1000);

// المنتج يحاول الإرسال بدون انتظار
match tx.try_send(event) {
    Ok(()) => {},
    Err(TrySendError::Full(_)) => {
        tracing::warn!("القناة ممتلئة، تجاهل الحدث");
        metrics::counter!("events_dropped").increment(1);
    },
    Err(TrySendError::Closed(_)) => break,
}

فوائد النمط

  1. الفصل — المنتجون لا يعرفون المستهلكين
  2. القابلية للتوسع — إضافة مستهلكين جدد بدون تغيير المنتجين
  3. الاختبار — اختبار كل مكون بشكل مستقل
  4. المرونة — تغيير أو إزالة مكونات بدون تأثير

الخلاصة

البنية القائمة على الأحداث مع نمط الحافلة تمكّن بناء أنظمة فورية مفصولة وقابلة للتوسع في Rust. المفتاح هو اختيار نوع القناة المناسب (broadcast للتوزيع، mpsc للنقطة لنقطة) والتعامل الصحيح مع الضغط الخلفي.

الوسوم