use core::time::Duration;
use std::sync::{Arc, Mutex};
use std::time::Instant;
use pipe_io::source::IterSource;
use pipe_io::{sink::VecSink, Clock, Pipeline, Window, WindowPolicy};
#[derive(Clone)]
struct ScriptedClock {
times: Arc<Mutex<std::vec::IntoIter<Instant>>>,
fallback: Arc<Mutex<Instant>>,
}
impl ScriptedClock {
fn new(times: Vec<Instant>) -> Self {
let last = *times.last().expect("at least one time");
Self {
times: Arc::new(Mutex::new(times.into_iter())),
fallback: Arc::new(Mutex::new(last)),
}
}
}
impl Clock for ScriptedClock {
fn now(&self) -> Instant {
let mut iter = self.times.lock().unwrap();
if let Some(t) = iter.next() {
*self.fallback.lock().unwrap() = t;
t
} else {
*self.fallback.lock().unwrap()
}
}
}
fn main() {
let t0 = Instant::now();
let clock = ScriptedClock::new(vec![
t0, t0 + Duration::from_secs(3), t0 + Duration::from_secs(9), t0 + Duration::from_secs(12), t0 + Duration::from_secs(18), t0 + Duration::from_secs(22), t0 + Duration::from_secs(25), ]);
let sink = VecSink::<u64>::new();
let handle = sink.handle();
Pipeline::from_source(IterSource::new(vec![5u64, 7, 3, 8, 2, 4]))
.window_with(
WindowPolicy::Tumbling {
size: Duration::from_secs(10),
},
clock,
)
.map(|w: Window<u64>| w.into_inner().iter().sum::<u64>())
.sink(sink)
.run()
.expect("pipeline run");
let rollups = handle.take();
println!("emitted {} window rollups: {:?}", rollups.len(), rollups);
assert_eq!(rollups, vec![15, 10, 4]);
}