1use super::{CronSchedule, JobTimeWindow};
2use chrono::{DateTime, Utc};
3use chrono_tz::{Asia::Shanghai, Tz};
4use std::time::Duration;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct StaggeredIntervalSchedule {
9 pub every: Duration,
10 pub seed: Option<String>,
11}
12
13impl StaggeredIntervalSchedule {
14 pub fn new(every: Duration) -> Self {
15 Self { every, seed: None }
16 }
17
18 pub fn with_seed(mut self, seed: impl Into<String>) -> Self {
19 self.seed = Some(seed.into());
20 self
21 }
22}
23
24#[derive(Debug, Clone, PartialEq, Eq)]
26pub struct GroupedIntervalSchedule {
27 pub every: Duration,
28 pub group_size: u32,
29 pub member_index: u32,
30 pub group_seed: Option<String>,
31}
32
33impl GroupedIntervalSchedule {
34 pub fn new(every: Duration, group_size: u32, member_index: u32) -> Self {
35 Self {
36 every,
37 group_size,
38 member_index,
39 group_seed: None,
40 }
41 }
42
43 pub fn with_group_seed(mut self, group_seed: impl Into<String>) -> Self {
44 self.group_seed = Some(group_seed.into());
45 self
46 }
47}
48
49#[derive(Debug, Clone, PartialEq, Eq)]
51pub struct IntervalWindow {
52 pub window: JobTimeWindow,
53 pub every: Option<Duration>,
54}
55
56impl IntervalWindow {
57 pub fn new(window: JobTimeWindow, every: Option<Duration>) -> Self {
58 Self { window, every }
59 }
60}
61
62#[derive(Debug, Clone, PartialEq, Eq)]
67pub struct WindowedIntervalSchedule {
68 pub default_every: Option<Duration>,
69 pub windows: Vec<IntervalWindow>,
70}
71
72impl WindowedIntervalSchedule {
73 pub fn new(default_every: Option<Duration>) -> Self {
74 Self {
75 default_every,
76 windows: Vec::new(),
77 }
78 }
79
80 pub fn with_window(mut self, window: JobTimeWindow, every: Option<Duration>) -> Self {
81 self.windows.push(IntervalWindow::new(window, every));
82 self
83 }
84}
85
86#[derive(Debug, Clone, PartialEq, Eq)]
87pub enum Schedule {
88 Interval(Duration),
90 StaggeredInterval(StaggeredIntervalSchedule),
95 GroupedInterval(GroupedIntervalSchedule),
102 WindowedInterval(WindowedIntervalSchedule),
104 AtTimes(Vec<DateTime<Tz>>),
109 Cron(CronSchedule),
114}
115
116#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
117pub enum MissedRunPolicy {
118 Skip,
119 #[default]
120 CatchUpOnce,
121 ReplayAll,
122}
123
124#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
125pub enum OverlapPolicy {
126 #[default]
127 Forbid,
128 QueueOne,
129 AllowParallel,
130}
131
132#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
133pub enum TerminalStatePolicy {
134 #[default]
135 Retain,
136 Delete,
137}
138
139#[derive(Debug, Clone)]
140pub struct SchedulerConfig {
141 pub timezone: Tz,
147 pub history_limit: usize,
149 pub terminal_state_policy: TerminalStatePolicy,
152}
153
154impl Default for SchedulerConfig {
155 fn default() -> Self {
156 Self {
157 timezone: Shanghai,
158 history_limit: 32,
159 terminal_state_policy: TerminalStatePolicy::Retain,
160 }
161 }
162}
163
164impl Schedule {
165 pub fn staggered_interval(every: Duration) -> Self {
168 Self::StaggeredInterval(StaggeredIntervalSchedule::new(every))
169 }
170
171 pub fn staggered_interval_with_seed(every: Duration, seed: impl Into<String>) -> Self {
173 Self::StaggeredInterval(StaggeredIntervalSchedule::new(every).with_seed(seed))
174 }
175
176 pub fn grouped_interval(every: Duration, group_size: u32, member_index: u32) -> Self {
178 Self::GroupedInterval(GroupedIntervalSchedule::new(
179 every,
180 group_size,
181 member_index,
182 ))
183 }
184
185 pub fn grouped_interval_with_seed(
188 every: Duration,
189 group_size: u32,
190 member_index: u32,
191 group_seed: impl Into<String>,
192 ) -> Self {
193 Self::GroupedInterval(
194 GroupedIntervalSchedule::new(every, group_size, member_index)
195 .with_group_seed(group_seed),
196 )
197 }
198
199 pub fn windowed_interval(default_every: Option<Duration>) -> Self {
201 Self::WindowedInterval(WindowedIntervalSchedule::new(default_every))
202 }
203}
204
205pub(crate) fn utc_time(value: DateTime<Tz>) -> DateTime<Utc> {
206 value.with_timezone(&Utc)
207}