celery/beat/schedule/
mod.rs

1//! This module contains the definition of application-provided schedules.
2//!
3//! These structs have not changed a lot compared to Python: in Python there are three
4//! different types of schedules: `schedule` (corresponding to [`DeltaSchedule`]),
5//! `crontab` (corresponding to [`CronSchedule`]), `solar` (not implemented yet).
6use std::any::Any;
7use std::time::{Duration, SystemTime};
8
9mod cron;
10pub use cron::CronSchedule;
11
12mod descriptor;
13pub use descriptor::ScheduleDescriptor;
14
15/// The trait that all schedules implement.
16pub trait Schedule: Any {
17    /// Compute when a task should be executed again.
18    /// If this method returns `None` then the task should
19    /// never run again and it is safe to remove it from the
20    /// list of scheduled tasks.
21    fn next_call_at(&self, last_run_at: Option<SystemTime>) -> Option<SystemTime>;
22
23    /// Describe this schedule so it can be serialized for persistence.
24    fn describe(&self) -> Option<ScheduleDescriptor> {
25        None
26    }
27}
28
29/// A schedule that can be used to execute tasks at regular intervals.
30pub struct DeltaSchedule {
31    interval: Duration,
32}
33
34impl DeltaSchedule {
35    /// Create a new time delta schedule which can be used to execute a task
36    /// forever, starting immediately and with the given `interval`
37    /// between subsequent executions.
38    pub fn new(interval: Duration) -> DeltaSchedule {
39        DeltaSchedule { interval }
40    }
41
42    pub fn interval(&self) -> Duration {
43        self.interval
44    }
45}
46
47impl Schedule for DeltaSchedule {
48    fn next_call_at(&self, last_run_at: Option<SystemTime>) -> Option<SystemTime> {
49        match last_run_at {
50            Some(last_run_at) => Some(
51                last_run_at
52                    .checked_add(self.interval)
53                    .expect("Invalid SystemTime encountered"),
54            ),
55            None => Some(SystemTime::now()),
56        }
57    }
58
59    fn describe(&self) -> Option<ScheduleDescriptor> {
60        Some(ScheduleDescriptor::delta(self.interval))
61    }
62}