From c61d301e1905b38beb593beddb26290747dc95ab Mon Sep 17 00:00:00 2001 From: cool-mist Date: Wed, 19 Aug 2026 12:45:37 +0530 Subject: [PATCH] Core functions --- crates/hd-bus/src/lib.rs | 170 ++++++++++++++++++++++++++++++--------- 1 file changed, 133 insertions(+), 37 deletions(-) diff --git a/crates/hd-bus/src/lib.rs b/crates/hd-bus/src/lib.rs index 65520f5..78711d6 100644 --- a/crates/hd-bus/src/lib.rs +++ b/crates/hd-bus/src/lib.rs @@ -1,6 +1,4 @@ -use std::{ - collections::{HashMap, VecDeque}, sync::RwLock, thread::{self, JoinHandle}, time::Duration, -}; +use std::sync::{Arc, RwLock}; pub type EventId = u64; pub type SubscriptionId = u64; @@ -10,72 +8,170 @@ pub enum HError { } pub struct Event { - id: u64, - topic_name: String, - data_utf8: Vec, + id: EventId, + pub data: EventData, } +pub struct EventData { + pub subject: String, + pub data_utf8: Vec, +} + +// Add Event event_bus scope W +// Add subscription event_bus scope W +// Poll subscription event_bus scope R + subscription scope R +// Ack subscription event_bus scope R + subscription scope W +// Remove subscription event_bus scope W +// Cleanup Event event_bus scope W pub struct EventBus { - queue: RwLock>, - subscriptions: RwLock>, + inner: Arc>, } -pub struct SubscriptionRequest { - topic_pattern: String, +struct EventBusInner { + next_event_id: EventId, + events: Vec>, + subscriptions: RwLock, +} + +impl EventBusInner { + fn new() -> Self { + let subscriptions = SubscriptionsInner { + next_subscription_id: 0, + subscriptions: Vec::new(), + }; + + Self { + next_event_id: 0, + events: Vec::new(), + subscriptions: RwLock::new(subscriptions), + } + } +} + +struct SubscriptionsInner { + next_subscription_id: SubscriptionId, + subscriptions: Vec, } pub struct Subscription { - id: u64, - request: SubscriptionRequest, + id: SubscriptionId, + // Return events exclusive of the cursor on a poll + cursor: EventId, +} + +pub struct PollResult { + pub events: Vec>, + pub cursor_end: EventId, } impl EventBus { pub fn new() -> Self { Self { - queue: RwLock::new(VecDeque::new()), - subscriptions: RwLock::new(Vec::new()), + inner: Arc::new(RwLock::new(EventBusInner::new())), } } - pub fn publish(&self, evt: Event) -> Result<(), HError> { - let mut queue = self - .queue + pub fn publish(&self, evt: EventData) -> Result<(), HError> { + let mut bus = self + .inner .write() .map_err(|e| HError::BusLockPoisoned(e.to_string()))?; - queue.push_back(evt); + + let next_event_id = &mut bus.next_event_id; + let event = Event { + id: *next_event_id, + data: evt, + }; + + *next_event_id += 1; + + let events = &mut bus.events; + events.push(Arc::new(event)); Ok(()) } - pub fn subscribe(&self, request: SubscriptionRequest) -> Result<(), HError> { - let mut subscriptions = self + pub fn subscribe(&self) -> Result { + let bus = self + .inner + .write() + .map_err(|e| HError::BusLockPoisoned(e.to_string()))?; + + let subscriptions = &mut bus .subscriptions .write() .map_err(|e| HError::BusLockPoisoned(e.to_string()))?; - let last_id = subscriptions.last().map(|s| s.id).unwrap_or(0); + let next_subscription_id = &mut subscriptions.next_subscription_id; let subscription = Subscription { - id: last_id + 1, - request, + id: *next_subscription_id, + cursor: 0, }; - subscriptions.push(subscription); - Ok(()) + + *next_subscription_id += 1; + + let ret = subscription.id; + subscriptions.subscriptions.push(subscription); + Ok(ret) } -} -struct EventBusProcessor { - last_id: u64, - subscriptions_queue: RwLock>, -} + pub fn poll(&self, id: SubscriptionId, max: usize) -> Result { + let bus = self + .inner + .read() + .map_err(|e| HError::BusLockPoisoned(e.to_string()))?; -impl EventBusProcessor { - fn start() -> JoinHandle { - thread::spawn(|| { - loop { - thread::sleep(Duration::from_secs(1)); + let mut cursor = 0; + + { + let subscriptions = &mut bus + .subscriptions + .read() + .map_err(|e| HError::BusLockPoisoned(e.to_string()))?; + + for sub in &subscriptions.subscriptions { + if sub.id == id { + cursor = sub.cursor; + break; + } } + } - return 0; - }) + let mut events = Vec::new(); + let mut cursor_end = cursor; + for evt in &bus.events { + if evt.id >= cursor { + events.push(evt.clone()); + cursor_end = evt.id; + if events.len() >= max { + break; + } + } + } + + Ok(PollResult { events, cursor_end }) + } + + pub fn ack(&self, id: SubscriptionId, cursor: EventId) -> Result<(), HError> { + let bus = self + .inner + .read() + .map_err(|e| HError::BusLockPoisoned(e.to_string()))?; + + { + let subscriptions = &mut bus + .subscriptions + .write() + .map_err(|e| HError::BusLockPoisoned(e.to_string()))?; + + for sub in &mut subscriptions.subscriptions { + if sub.id == id { + sub.cursor = cursor; + break; + } + } + } + + Ok(()) } }