aligned_task_scheduler/
lib.rs1use tokio::time::{sleep, Duration};
2use std::time::{SystemTime, UNIX_EPOCH};
3
4pub struct AlignedTaskScheduler {
5 interval_minutes: u64,
6 offset_seconds: u64,
7}
8
9impl AlignedTaskScheduler {
10 pub fn new(interval_minutes: u64, offset_seconds: u64) -> Self {
13 AlignedTaskScheduler { interval_minutes, offset_seconds }
14 }
15
16 pub async fn run<F, Fut>(&self, mut task: F) -> !
19 where
20 F: FnMut(u64) -> Fut + Send + 'static,
21 Fut: std::future::Future<Output = ()> + Send + 'static,
22 {
23 loop {
24 let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs();
25 let interval_secs = self.interval_minutes * 60;
26
27 let next_interval = ((now / interval_secs) + 1) * interval_secs;
29
30 let wait_secs_to_interval = next_interval - now;
31 sleep(Duration::from_secs(wait_secs_to_interval)).await;
33
34 if self.offset_seconds > 0 {
36 sleep(Duration::from_secs(self.offset_seconds)).await;
37 }
38
39 task(next_interval).await;
41 }
42 }
43}