syspulse_core/
scheduler.rs1use tokio_cron_scheduler::{Job, JobScheduler};
2use tracing::info;
3
4use crate::error::{Result, SyspulseError};
5
6pub struct Scheduler {
7 scheduler: JobScheduler,
8}
9
10impl Scheduler {
11 pub async fn new() -> Result<Self> {
12 let scheduler = JobScheduler::new()
13 .await
14 .map_err(|e| SyspulseError::Scheduler(e.to_string()))?;
15 Ok(Self { scheduler })
16 }
17
18 pub async fn schedule_daemon<F, Fut>(
21 &mut self,
22 name: &str,
23 cron_expr: &str,
24 callback: F,
25 ) -> Result<()>
26 where
27 F: Fn(String) -> Fut + Send + Sync + Clone + 'static,
28 Fut: std::future::Future<Output = ()> + Send,
29 {
30 let daemon_name = name.to_string();
31 let cb = callback.clone();
32 let job = Job::new_async(cron_expr, move |_uuid, _lock| {
33 let name = daemon_name.clone();
34 let cb = cb.clone();
35 Box::pin(async move {
36 info!("Cron trigger firing for daemon '{}'", name);
37 cb(name).await;
38 })
39 })
40 .map_err(|e| SyspulseError::Scheduler(e.to_string()))?;
41
42 self.scheduler
43 .add(job)
44 .await
45 .map_err(|e| SyspulseError::Scheduler(e.to_string()))?;
46 info!("Scheduled daemon '{}' with cron '{}'", name, cron_expr);
47 Ok(())
48 }
49
50 pub async fn start(&self) -> Result<()> {
52 self.scheduler
53 .start()
54 .await
55 .map_err(|e| SyspulseError::Scheduler(e.to_string()))?;
56 info!("Cron scheduler started");
57 Ok(())
58 }
59
60 pub async fn shutdown(&mut self) -> Result<()> {
62 self.scheduler
63 .shutdown()
64 .await
65 .map_err(|e| SyspulseError::Scheduler(e.to_string()))?;
66 info!("Cron scheduler shut down");
67 Ok(())
68 }
69}