cja/cron/mod.rs
1//! Scheduled task execution with interval-based and cron expression scheduling.
2//!
3//! The cron system runs jobs on a schedule, either at fixed intervals or using
4//! standard cron expressions with timezone support.
5//!
6//! # Interval Scheduling
7//!
8//! ```rust,ignore
9//! use cja::cron::CronRegistry;
10//! use std::time::Duration;
11//!
12//! let mut registry = CronRegistry::new();
13//!
14//! // Run a Job every 60 seconds
15//! registry.register_job(MyJob, Some("Description"), Duration::from_secs(60));
16//! ```
17//!
18//! # Cron Expression Scheduling
19//!
20//! ```rust,ignore
21//! // Run at 9 AM every day (cron syntax: sec min hour day month weekday year)
22//! registry.register_job_with_cron(
23//! DailyReportJob,
24//! Some("Daily report"),
25//! "0 0 9 * * * *",
26//! )?;
27//! ```
28//!
29//! # Running the Worker
30//!
31//! ```rust,ignore
32//! use cja::cron::Worker;
33//! use chrono_tz::US::Eastern;
34//! use std::time::Duration;
35//!
36//! // With timezone and custom poll interval
37//! Worker::new_with_timezone(app_state, registry, Eastern, Duration::from_secs(30))
38//! .run(shutdown_token)
39//! .await?;
40//!
41//! // Or with defaults (UTC, 60s poll interval)
42//! Worker::new(app_state, registry)
43//! .run(shutdown_token)
44//! .await?;
45//! ```
46//!
47//! The default poll interval is 60 seconds. To change it, use
48//! [`Worker::new_with_timezone`] — there is no `new_with_interval` method.
49//!
50//! # Queue Pileup Warning
51//!
52//! If a cron job takes longer to run than its scheduling interval, the queue
53//! grows unbounded (CJA does not deduplicate). For example, a 60-second interval
54//! with a 20-minute job runtime queues ~20 copies before the first finishes.
55//!
56//! Mitigations: use longer intervals, add job-level deduplication, or set timeouts.
57
58pub(crate) mod registry;
59pub use registry::{CronRegistry, CronSchedule, IntervalSchedule, Schedule};
60pub use tokio_util::sync::CancellationToken;
61
62mod worker;
63pub use worker::Worker;