use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use chrono::{DateTime, Utc};
use chrono_tz::Tz;
use tokio_util::sync::CancellationToken;
use crate::CamelError;
#[derive(Debug, Clone)]
pub struct CronSchedule {
pub expression: String,
pub time_zone: Tz,
pub trigger_id: String,
pub route_id: Option<String>,
}
#[derive(Debug, Clone)]
pub struct CronFire {
pub scheduled_at: DateTime<Utc>,
pub fired_at: DateTime<Utc>,
pub counter: u64,
}
pub type CronCallback = Arc<
dyn Fn(CronFire) -> Pin<Box<dyn Future<Output = Result<(), CamelError>> + Send>> + Send + Sync,
>;
#[async_trait::async_trait]
pub trait CronService: Send + Sync {
async fn run(
&self,
schedule: &CronSchedule,
callback: CronCallback,
cancel: CancellationToken,
) -> Result<(), CamelError>;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn cron_schedule_construction() {
let schedule = CronSchedule {
expression: "0 0 2 * * *".to_string(),
time_zone: Tz::UTC,
trigger_id: "nightly".to_string(),
route_id: Some("route-1".to_string()),
};
assert_eq!(schedule.expression, "0 0 2 * * *");
assert_eq!(schedule.trigger_id, "nightly");
assert_eq!(schedule.route_id.as_deref(), Some("route-1"));
}
#[test]
fn cron_fire_construction() {
let now = Utc::now();
let fire = CronFire {
scheduled_at: now,
fired_at: now,
counter: 1,
};
assert_eq!(fire.counter, 1);
}
}