use crate::error::Result;
use crate::storage::schema::EntityTypeTag;
use crate::storage::StorageEngine;
use crate::watch::WatchEvent;
const DEFAULT_BATCH_LIMIT: usize = 1000;
pub struct ChangePoller {
last_seq: u64,
batch_limit: usize,
}
impl ChangePoller {
pub fn new() -> Self {
Self {
last_seq: 0,
batch_limit: DEFAULT_BATCH_LIMIT,
}
}
pub fn from_sequence(seq: u64) -> Self {
Self {
last_seq: seq,
batch_limit: DEFAULT_BATCH_LIMIT,
}
}
pub fn with_batch_limit(mut self, limit: usize) -> Self {
self.batch_limit = limit;
self
}
pub fn last_sequence(&self) -> u64 {
self.last_seq
}
pub fn poll(&mut self, storage: &dyn StorageEngine) -> Result<Vec<WatchEvent>> {
let (records, new_seq) = storage.poll_watch_events(self.last_seq, self.batch_limit)?;
self.last_seq = new_seq;
Ok(records
.into_iter()
.filter(|r| r.entity_type == EntityTypeTag::Experience)
.map(WatchEvent::from)
.collect())
}
#[cfg(feature = "sync")]
pub fn poll_sync_events(
&mut self,
storage: &dyn StorageEngine,
) -> Result<Vec<(u64, crate::storage::schema::WatchEventRecord)>> {
let events = storage.poll_sync_events(self.last_seq, self.batch_limit)?;
if let Some((last_seq, _)) = events.last() {
self.last_seq = *last_seq;
}
Ok(events)
}
}
impl Default for ChangePoller {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_change_poller_new_starts_at_zero() {
let poller = ChangePoller::new();
assert_eq!(poller.last_sequence(), 0);
}
#[test]
fn test_change_poller_from_sequence() {
let poller = ChangePoller::from_sequence(42);
assert_eq!(poller.last_sequence(), 42);
}
#[test]
fn test_change_poller_default() {
let poller = ChangePoller::default();
assert_eq!(poller.last_sequence(), 0);
}
#[test]
fn test_change_poller_with_batch_limit() {
let poller = ChangePoller::new().with_batch_limit(10);
assert_eq!(poller.batch_limit, 10);
}
}