Core functions

This commit is contained in:
2026-08-19 12:45:37 +05:30
parent 4f5a9c7dc3
commit c61d301e19
+133 -37
View File
@@ -1,6 +1,4 @@
use std::{ use std::sync::{Arc, RwLock};
collections::{HashMap, VecDeque}, sync::RwLock, thread::{self, JoinHandle}, time::Duration,
};
pub type EventId = u64; pub type EventId = u64;
pub type SubscriptionId = u64; pub type SubscriptionId = u64;
@@ -10,72 +8,170 @@ pub enum HError {
} }
pub struct Event { pub struct Event {
id: u64, id: EventId,
topic_name: String, pub data: EventData,
data_utf8: Vec<u8>,
} }
pub struct EventData {
pub subject: String,
pub data_utf8: Vec<u8>,
}
// 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 { pub struct EventBus {
queue: RwLock<VecDeque<Event>>, inner: Arc<RwLock<EventBusInner>>,
subscriptions: RwLock<Vec<Subscription>>,
} }
pub struct SubscriptionRequest { struct EventBusInner {
topic_pattern: String, next_event_id: EventId,
events: Vec<Arc<Event>>,
subscriptions: RwLock<SubscriptionsInner>,
}
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<Subscription>,
} }
pub struct Subscription { pub struct Subscription {
id: u64, id: SubscriptionId,
request: SubscriptionRequest, // Return events exclusive of the cursor on a poll
cursor: EventId,
}
pub struct PollResult {
pub events: Vec<Arc<Event>>,
pub cursor_end: EventId,
} }
impl EventBus { impl EventBus {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
queue: RwLock::new(VecDeque::new()), inner: Arc::new(RwLock::new(EventBusInner::new())),
subscriptions: RwLock::new(Vec::new()),
} }
} }
pub fn publish(&self, evt: Event) -> Result<(), HError> { pub fn publish(&self, evt: EventData) -> Result<(), HError> {
let mut queue = self let mut bus = self
.queue .inner
.write() .write()
.map_err(|e| HError::BusLockPoisoned(e.to_string()))?; .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(()) Ok(())
} }
pub fn subscribe(&self, request: SubscriptionRequest) -> Result<(), HError> { pub fn subscribe(&self) -> Result<SubscriptionId, HError> {
let mut subscriptions = self let bus = self
.inner
.write()
.map_err(|e| HError::BusLockPoisoned(e.to_string()))?;
let subscriptions = &mut bus
.subscriptions .subscriptions
.write() .write()
.map_err(|e| HError::BusLockPoisoned(e.to_string()))?; .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 { let subscription = Subscription {
id: last_id + 1, id: *next_subscription_id,
request, cursor: 0,
}; };
subscriptions.push(subscription);
Ok(()) *next_subscription_id += 1;
let ret = subscription.id;
subscriptions.subscriptions.push(subscription);
Ok(ret)
} }
}
struct EventBusProcessor { pub fn poll(&self, id: SubscriptionId, max: usize) -> Result<PollResult, HError> {
last_id: u64, let bus = self
subscriptions_queue: RwLock<HashMap<SubscriptionId, EventId>>, .inner
} .read()
.map_err(|e| HError::BusLockPoisoned(e.to_string()))?;
impl EventBusProcessor { let mut cursor = 0;
fn start() -> JoinHandle<u64> {
thread::spawn(|| { {
loop { let subscriptions = &mut bus
thread::sleep(Duration::from_secs(1)); .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(())
} }
} }