ic_cron/
macros.rs

1#[macro_export]
2macro_rules! implement_cron {
3    () => {
4        pub static mut _CRON_STATE: Option<ic_cron::task_scheduler::TaskScheduler> = None;
5
6        pub fn get_cron_state() -> &'static mut ic_cron::task_scheduler::TaskScheduler {
7            unsafe {
8                match _CRON_STATE.as_mut() {
9                    Some(cron) => cron,
10                    None => {
11                        _put_cron_state(Some(ic_cron::task_scheduler::TaskScheduler::default()));
12                        get_cron_state()
13                    }
14                }
15            }
16        }
17
18        pub fn _take_cron_state() -> Option<ic_cron::task_scheduler::TaskScheduler> {
19            unsafe { _CRON_STATE.take() }
20        }
21
22        pub fn _put_cron_state(state: Option<ic_cron::task_scheduler::TaskScheduler>) {
23            unsafe {
24                _CRON_STATE = state;
25            }
26        }
27
28        pub fn cron_enqueue<Payload: ic_cdk::export::candid::CandidType>(
29            payload: Payload,
30            scheduling_options: ic_cron::types::SchedulingOptions,
31        ) -> ic_cdk::export::candid::Result<ic_cron::types::TaskId> {
32            let cron = get_cron_state();
33
34            let id = cron.enqueue(payload, scheduling_options, ic_cdk::api::time())?;
35
36            Ok(id)
37        }
38
39        pub fn cron_dequeue(
40            task_id: ic_cron::types::TaskId,
41        ) -> Option<ic_cron::types::ScheduledTask> {
42            get_cron_state().dequeue(task_id)
43        }
44
45        pub fn cron_ready_tasks() -> Vec<ic_cron::types::ScheduledTask> {
46            get_cron_state().iterate(ic_cdk::api::time())
47        }
48    };
49}
50
51#[cfg(test)]
52mod tests {
53    use crate as ic_cron;
54    use crate::implement_cron;
55    use crate::task_scheduler::TaskScheduler;
56    use ic_cdk::storage::{stable_restore, stable_save};
57    use ic_cdk_macros::{heartbeat, post_upgrade, pre_upgrade};
58
59    implement_cron!();
60
61    #[pre_upgrade]
62    fn pre_upgrade_hook() {
63        let cron_state = _take_cron_state();
64
65        stable_save((cron_state,)).expect("Unable to save the state to stable memory");
66    }
67
68    #[post_upgrade]
69    fn post_upgrade_hook() {
70        let (cron_state,): (Option<TaskScheduler>,) =
71            stable_restore().expect("Unable to restore the state from stable memory");
72
73        _put_cron_state(cron_state);
74    }
75
76    #[heartbeat]
77    fn tick() {
78        let tasks = cron_ready_tasks();
79    }
80
81    #[test]
82    fn no_op() {
83        assert!(true);
84    }
85}