aligned_task_scheduler/
lib.rs

1use 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    /// interval_minutes:每隔多少分钟的整点执行
11    /// offset_seconds:在整点基础上增加多少秒的偏移执行
12    pub fn new(interval_minutes: u64, offset_seconds: u64) -> Self {
13        AlignedTaskScheduler { interval_minutes, offset_seconds }
14    }
15
16    /// 运行单个异步任务
17    /// task:返回()`的异步闭包
18    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            // 下一个整 interval_minutes 分钟的时间戳
28            let next_interval = ((now / interval_secs) + 1) * interval_secs;
29
30            let wait_secs_to_interval = next_interval - now;
31            // 等待直到整点
32            sleep(Duration::from_secs(wait_secs_to_interval)).await;
33
34            // 等待偏移秒数
35            if self.offset_seconds > 0 {
36                sleep(Duration::from_secs(self.offset_seconds)).await;
37            }
38
39            // 执行单个任务
40            task(next_interval).await;
41        }
42    }
43}