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 TimeWindowAlignment {
134 #[default]
135 Disabled,
136 AlignToNextWindow,
137}
138
139#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
140pub enum TerminalStatePolicy {
141 #[default]
142 Retain,
143 Delete,
144}
145
146#[derive(Debug, Clone)]
147pub struct SchedulerConfig {
148 pub timezone: Tz,
154 pub history_limit: usize,
156 pub terminal_state_policy: TerminalStatePolicy,
159}
160
161impl Default for SchedulerConfig {
162 fn default() -> Self {
163 Self {
164 timezone: Shanghai,
165 history_limit: 32,
166 terminal_state_policy: TerminalStatePolicy::Retain,
167 }
168 }
169}
170
171impl Schedule {
172 pub fn staggered_interval(every: Duration) -> Self {
175 Self::StaggeredInterval(StaggeredIntervalSchedule::new(every))
176 }
177
178 pub fn staggered_interval_with_seed(every: Duration, seed: impl Into<String>) -> Self {
180 Self::StaggeredInterval(StaggeredIntervalSchedule::new(every).with_seed(seed))
181 }
182
183 pub fn grouped_interval(every: Duration, group_size: u32, member_index: u32) -> Self {
185 Self::GroupedInterval(GroupedIntervalSchedule::new(
186 every,
187 group_size,
188 member_index,
189 ))
190 }
191
192 pub fn grouped_interval_with_seed(
195 every: Duration,
196 group_size: u32,
197 member_index: u32,
198 group_seed: impl Into<String>,
199 ) -> Self {
200 Self::GroupedInterval(
201 GroupedIntervalSchedule::new(every, group_size, member_index)
202 .with_group_seed(group_seed),
203 )
204 }
205
206 pub fn windowed_interval(default_every: Option<Duration>) -> Self {
208 Self::WindowedInterval(WindowedIntervalSchedule::new(default_every))
209 }
210}
211
212pub(crate) fn utc_time(value: DateTime<Tz>) -> DateTime<Utc> {
213 value.with_timezone(&Utc)
214}