Skip to main content

ic_canister_kit/functions/
schedule.rs

1use crate::types::DurationNanos;
2
3// ================== 异步执行代码 ==================
4// 不知道和 ic_cdk::spawn(future) 区别在哪里
5
6/// 异步执行代码
7#[inline]
8pub fn async_execute<Task>(task: Task) -> ic_cdk_timers::TimerId
9where
10    Task: Future<Output = ()> + 'static,
11{
12    ic_cdk_timers::set_timer(std::time::Duration::ZERO, task)
13}
14
15// ================== 功能 ==================
16
17pub use ic_cdk_timers::TimerId;
18
19/// 定时任务功能
20pub trait Schedulable {
21    /// 查询
22    fn schedule_find(&self) -> Option<DurationNanos>;
23    /// 修改
24    fn schedule_replace(&mut self, schedule: Option<DurationNanos>);
25}
26
27/// 停止任务
28#[inline]
29pub fn schedule_stop(timer_id: Option<TimerId>) {
30    if let Some(timer_id) = timer_id {
31        ic_cdk_timers::clear_timer(timer_id)
32    }
33}
34
35/// 启动任务
36#[inline]
37pub fn schedule_start<F>(schedule: &Option<DurationNanos>, task: impl FnMut() -> F + 'static) -> Option<TimerId>
38where
39    F: Future<Output = ()> + 'static,
40{
41    schedule.map(|interval| {
42        ic_cdk_timers::set_timer_interval(std::time::Duration::from_nanos(interval.into_inner() as u64), task)
43    })
44}
45
46// ================== 简单实现 ==================
47
48/// 定时任务简单实现
49pub mod basic {
50    use candid::CandidType;
51    use serde::{Deserialize, Serialize};
52
53    use crate::{functions::types::Schedulable, types::DurationNanos};
54
55    #[cfg(feature = "schedule")]
56    mod schedule {
57        use std::cell::RefCell;
58
59        use ic_cdk_timers::TimerId;
60
61        use crate::types::DurationNanos;
62
63        thread_local! {
64            static SCHEDULE: RefCell<Option<TimerId>> = RefCell::default(); // 定时任务 id 记录
65        }
66
67        /// 停止定时任务
68        #[inline]
69        pub fn stop_schedule() {
70            SCHEDULE.with_borrow_mut(|timer_id| crate::functions::schedule::schedule_stop(std::mem::take(timer_id)));
71        }
72
73        /// 启动定时任务
74        #[inline]
75        pub fn start_schedule<F>(schedule: &Option<DurationNanos>, task: impl FnMut() -> F + 'static)
76        where
77            F: Future<Output = ()> + 'static,
78        {
79            stop_schedule();
80            let new_timer_id = crate::functions::schedule::schedule_start(schedule, task);
81            SCHEDULE.with_borrow_mut(|timer_id| *timer_id = new_timer_id);
82        }
83    }
84    #[cfg(feature = "schedule")]
85    pub use schedule::*;
86
87    /// 周期定时任务
88    #[derive(CandidType, Serialize, Deserialize, Debug, Clone, Default)]
89    pub struct Schedule(Option<DurationNanos>);
90
91    impl Schedulable for Schedule {
92        // 查询
93        fn schedule_find(&self) -> Option<DurationNanos> {
94            self.0
95        }
96        // 修改
97        fn schedule_replace(&mut self, schedule: Option<DurationNanos>) {
98            self.0 = schedule
99        }
100    }
101}
102
103#[cfg(feature = "schedule")]
104pub use basic::{start_schedule, stop_schedule};