Skip to main content

reifydb_sub_task/
schedule.rs

1use std::time::{Duration, Instant};
2
3/// Defines when and how often a task should be executed
4#[derive(Debug, Clone)]
5pub enum Schedule {
6	/// Execute at fixed intervals (interval starts after task completion)
7	FixedInterval(Duration),
8	/// Execute once after a delay
9	Once(Duration),
10}
11
12impl Schedule {
13	/// Calculate the next execution time after the given instant
14	/// Returns None for one-shot tasks
15	pub fn next_execution(&self, after: Instant) -> Option<Instant> {
16		match self {
17			Schedule::FixedInterval(duration) => Some(after + *duration),
18			Schedule::Once(_) => None,
19		}
20	}
21
22	/// Get the initial delay for first execution
23	pub fn initial_delay(&self) -> Duration {
24		match self {
25			Schedule::FixedInterval(duration) => *duration,
26			Schedule::Once(delay) => *delay,
27		}
28	}
29
30	/// Validate the schedule
31	pub fn validate(&self) -> Result<(), String> {
32		match self {
33			Schedule::FixedInterval(duration) => {
34				if duration.is_zero() {
35					return Err("FixedInterval duration cannot be zero".to_string());
36				}
37				Ok(())
38			}
39			Schedule::Once(delay) => {
40				if delay.is_zero() {
41					return Err("Once delay cannot be zero".to_string());
42				}
43				Ok(())
44			}
45		}
46	}
47}
48
49#[cfg(test)]
50mod tests {
51	use super::*;
52
53	#[test]
54	fn test_fixed_interval_next_execution() {
55		let schedule = Schedule::FixedInterval(Duration::from_secs(10));
56		let now = Instant::now();
57		let next = schedule.next_execution(now);
58		assert!(next.is_some());
59		assert_eq!(next.unwrap(), now + Duration::from_secs(10));
60	}
61
62	#[test]
63	fn test_once_next_execution() {
64		let schedule = Schedule::Once(Duration::from_secs(5));
65		let now = Instant::now();
66		let next = schedule.next_execution(now);
67		assert!(next.is_none());
68	}
69
70	#[test]
71	fn test_initial_delay() {
72		let interval = Schedule::FixedInterval(Duration::from_secs(30));
73		assert_eq!(interval.initial_delay(), Duration::from_secs(30));
74
75		let once = Schedule::Once(Duration::from_secs(5));
76		assert_eq!(once.initial_delay(), Duration::from_secs(5));
77	}
78
79	#[test]
80	fn test_validation() {
81		let valid = Schedule::FixedInterval(Duration::from_secs(1));
82		assert!(valid.validate().is_ok());
83
84		let invalid = Schedule::FixedInterval(Duration::ZERO);
85		assert!(invalid.validate().is_err());
86	}
87}