Skip to main content

reifydb_sub_task/
schedule.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (c) 2026 ReifyDB
3
4use std::time::Duration;
5
6use reifydb_runtime::context::clock::Instant;
7
8#[derive(Debug, Clone)]
9pub enum Schedule {
10	FixedInterval(Duration),
11
12	Once(Duration),
13}
14
15impl Schedule {
16	pub fn next_execution(&self, after: Instant) -> Option<Instant> {
17		match self {
18			Schedule::FixedInterval(duration) => Some(after + *duration),
19			Schedule::Once(_) => None,
20		}
21	}
22
23	pub fn initial_delay(&self) -> Duration {
24		match self {
25			Schedule::FixedInterval(duration) => *duration,
26			Schedule::Once(delay) => *delay,
27		}
28	}
29
30	pub fn validate(&self) -> Result<(), String> {
31		match self {
32			Schedule::FixedInterval(duration) => {
33				if duration.is_zero() {
34					return Err("FixedInterval duration cannot be zero".to_string());
35				}
36				Ok(())
37			}
38			Schedule::Once(delay) => {
39				if delay.is_zero() {
40					return Err("Once delay cannot be zero".to_string());
41				}
42				Ok(())
43			}
44		}
45	}
46}
47
48#[cfg(test)]
49mod tests {
50	use reifydb_runtime::context::clock::Clock;
51
52	use super::*;
53
54	#[test]
55	fn test_fixed_interval_next_execution() {
56		let clock = Clock::Real;
57		let schedule = Schedule::FixedInterval(Duration::from_secs(10));
58		let now = clock.instant();
59		let next = schedule.next_execution(now.clone());
60		assert!(next.is_some());
61		assert_eq!(next.unwrap(), now + Duration::from_secs(10));
62	}
63
64	#[test]
65	fn test_once_next_execution() {
66		let clock = Clock::Real;
67		let schedule = Schedule::Once(Duration::from_secs(5));
68		let now = clock.instant();
69		let next = schedule.next_execution(now);
70		assert!(next.is_none());
71	}
72
73	#[test]
74	fn test_initial_delay() {
75		let interval = Schedule::FixedInterval(Duration::from_secs(30));
76		assert_eq!(interval.initial_delay(), Duration::from_secs(30));
77
78		let once = Schedule::Once(Duration::from_secs(5));
79		assert_eq!(once.initial_delay(), Duration::from_secs(5));
80	}
81
82	#[test]
83	fn test_validation() {
84		let valid = Schedule::FixedInterval(Duration::from_secs(1));
85		assert!(valid.validate().is_ok());
86
87		let invalid = Schedule::FixedInterval(Duration::ZERO);
88		assert!(invalid.validate().is_err());
89	}
90}