use super::job::{PeriodicScheduler, QueryFn, RegisteredJob};
use crate::runner::TaskStore;
use serde::Serialize;
use std::future::Future;
use std::sync::Arc;
use std::time::Duration;
pub struct SchedulerBuilder<S: TaskStore> {
task_store: S,
jobs: Vec<RegisteredJob>,
pending_run_on_start: bool,
}
impl<S: TaskStore + 'static> SchedulerBuilder<S> {
pub fn new(task_store: S) -> Self {
Self {
task_store,
jobs: Vec::new(),
pending_run_on_start: false,
}
}
pub fn job<F, Fut, T>(
mut self,
pipeline_name: &'static str,
interval: Duration,
query_fn: F,
) -> Self
where
F: Fn() -> Fut + Send + Sync + 'static,
Fut: Future<Output = Vec<T>> + Send + 'static,
T: Serialize + 'static,
{
let query_fn: QueryFn = Arc::new(move || {
let fut = query_fn();
Box::pin(async move {
let items = fut.await;
items
.into_iter()
.filter_map(|item| serde_json::to_value(item).ok())
.collect()
})
});
self.jobs.push(RegisteredJob {
pipeline_name,
interval,
query_fn,
run_on_start: self.pending_run_on_start,
});
self.pending_run_on_start = false;
self
}
pub fn run_on_start(mut self, run: bool) -> Self {
if let Some(job) = self.jobs.last_mut() {
job.run_on_start = run;
}
self
}
pub fn build(self) -> PeriodicScheduler<S> {
PeriodicScheduler::new(self.task_store, self.jobs)
}
}