#![allow(missing_docs)]
use core::time::Duration;
use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::{Arc, Mutex};
use std::time::Instant;
use taktora_executor::{ControlFlow, ExecutionMonitor, Executor, TaskId, item_with_triggers};
#[derive(Default)]
struct RecordingMonitor {
pre: AtomicU32,
post: AtomicU32,
times: Mutex<Vec<(TaskId, Duration, bool)>>,
}
impl ExecutionMonitor for RecordingMonitor {
fn pre_execute(&self, _: TaskId, _: Instant) {
self.pre.fetch_add(1, Ordering::SeqCst);
}
fn post_execute(&self, t: TaskId, _: Instant, took: Duration, ok: bool) {
self.post.fetch_add(1, Ordering::SeqCst);
self.times.lock().unwrap().push((t, took, ok));
}
}
#[test]
fn monitor_brackets_each_execute() {
let mon = Arc::new(RecordingMonitor::default());
let mut exec = Executor::builder()
.worker_threads(0)
.monitor(Arc::clone(&mon) as Arc<dyn ExecutionMonitor>)
.build()
.unwrap();
exec.add(item_with_triggers(
|d| {
d.interval(Duration::from_millis(10));
Ok(())
},
|_| Ok(ControlFlow::Continue),
))
.unwrap();
exec.run_n(3).unwrap();
assert_eq!(mon.pre.load(Ordering::SeqCst), 3);
assert_eq!(mon.post.load(Ordering::SeqCst), 3);
assert!(mon.times.lock().unwrap().iter().all(|(_, _, ok)| *ok));
}