use super::{CronSchedule, JobTimeWindow};
use chrono::{DateTime, Utc};
use chrono_tz::{Asia::Shanghai, Tz};
use std::time::Duration;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StaggeredIntervalSchedule {
pub every: Duration,
pub seed: Option<String>,
}
impl StaggeredIntervalSchedule {
pub fn new(every: Duration) -> Self {
Self { every, seed: None }
}
pub fn with_seed(mut self, seed: impl Into<String>) -> Self {
self.seed = Some(seed.into());
self
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GroupedIntervalSchedule {
pub every: Duration,
pub group_size: u32,
pub member_index: u32,
pub group_seed: Option<String>,
}
impl GroupedIntervalSchedule {
pub fn new(every: Duration, group_size: u32, member_index: u32) -> Self {
Self {
every,
group_size,
member_index,
group_seed: None,
}
}
pub fn with_group_seed(mut self, group_seed: impl Into<String>) -> Self {
self.group_seed = Some(group_seed.into());
self
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct IntervalWindow {
pub window: JobTimeWindow,
pub every: Option<Duration>,
}
impl IntervalWindow {
pub fn new(window: JobTimeWindow, every: Option<Duration>) -> Self {
Self { window, every }
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct WindowedIntervalSchedule {
pub default_every: Option<Duration>,
pub windows: Vec<IntervalWindow>,
}
impl WindowedIntervalSchedule {
pub fn new(default_every: Option<Duration>) -> Self {
Self {
default_every,
windows: Vec::new(),
}
}
pub fn with_window(mut self, window: JobTimeWindow, every: Option<Duration>) -> Self {
self.windows.push(IntervalWindow::new(window, every));
self
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Schedule {
Interval(Duration),
StaggeredInterval(StaggeredIntervalSchedule),
GroupedInterval(GroupedIntervalSchedule),
WindowedInterval(WindowedIntervalSchedule),
AtTimes(Vec<DateTime<Tz>>),
Cron(CronSchedule),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum MissedRunPolicy {
Skip,
#[default]
CatchUpOnce,
ReplayAll,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum OverlapPolicy {
#[default]
Forbid,
QueueOne,
AllowParallel,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum TerminalStatePolicy {
#[default]
Retain,
Delete,
}
#[derive(Debug, Clone)]
pub struct SchedulerConfig {
pub timezone: Tz,
pub history_limit: usize,
pub terminal_state_policy: TerminalStatePolicy,
}
impl Default for SchedulerConfig {
fn default() -> Self {
Self {
timezone: Shanghai,
history_limit: 32,
terminal_state_policy: TerminalStatePolicy::Retain,
}
}
}
impl Schedule {
pub fn staggered_interval(every: Duration) -> Self {
Self::StaggeredInterval(StaggeredIntervalSchedule::new(every))
}
pub fn staggered_interval_with_seed(every: Duration, seed: impl Into<String>) -> Self {
Self::StaggeredInterval(StaggeredIntervalSchedule::new(every).with_seed(seed))
}
pub fn grouped_interval(every: Duration, group_size: u32, member_index: u32) -> Self {
Self::GroupedInterval(GroupedIntervalSchedule::new(
every,
group_size,
member_index,
))
}
pub fn grouped_interval_with_seed(
every: Duration,
group_size: u32,
member_index: u32,
group_seed: impl Into<String>,
) -> Self {
Self::GroupedInterval(
GroupedIntervalSchedule::new(every, group_size, member_index)
.with_group_seed(group_seed),
)
}
pub fn windowed_interval(default_every: Option<Duration>) -> Self {
Self::WindowedInterval(WindowedIntervalSchedule::new(default_every))
}
}
pub(crate) fn utc_time(value: DateTime<Tz>) -> DateTime<Utc> {
value.with_timezone(&Utc)
}