1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#[macro_export]
macro_rules! implement_cron {
() => {
static mut CRON: Option<ic_cron::task_scheduler::TaskScheduler> = None;
pub fn get_cron_state() -> &'static mut ic_cron::task_scheduler::TaskScheduler {
unsafe {
match CRON.as_mut() {
Some(cron) => cron,
None => {
CRON = Some(ic_cron::task_scheduler::TaskScheduler::default());
get_cron_state()
}
}
}
}
pub fn cron_enqueue<Payload: ic_cdk::export::candid::CandidType>(
kind: u8,
payload: Payload,
scheduling_interval: ic_cron::types::SchedulingInterval,
) -> ic_cdk::export::candid::Result<ic_cron::types::TaskId> {
let cron = get_cron_state();
let id = cron.enqueue(kind, payload, scheduling_interval, ic_cdk::api::time())?;
Ok(id)
}
pub fn cron_dequeue(
task_id: ic_cron::types::TaskId,
) -> Option<ic_cron::types::ScheduledTask> {
get_cron_state().dequeue(task_id)
}
pub fn cron_ready_tasks() -> Vec<ic_cron::types::ScheduledTask> {
get_cron_state().iterate(ic_cdk::api::time())
}
};
}
#[macro_export]
macro_rules! u8_enum {
($(#[$meta:meta])* $vis:vis enum $name:ident {
$($(#[$vmeta:meta])* $vname:ident $(= $val:expr)?,)*
}) => {
$(#[$meta])*
$vis enum $name {
$($(#[$vmeta])* $vname $(= $val)?,)*
}
impl std::convert::TryFrom<u8> for $name {
type Error = ();
fn try_from(v: u8) -> Result<Self, Self::Error> {
match v {
$(x if x == $name::$vname as u8 => Ok($name::$vname),)*
_ => Err(()),
}
}
}
}
}
#[cfg(test)]
mod tests {
use crate as ic_cron;
use crate::implement_cron;
use core::convert::TryInto;
implement_cron!();
u8_enum! {
pub enum HanlderKind {
First,
Second,
}
}
#[export_name = "canister_heartbeat"]
fn heartbeat() {
for task in cron_ready_tasks() {
match task.get_kind().try_into() {
Ok(HanlderKind::First) => {}
Ok(HanlderKind::Second) => {}
Err(_) => {}
}
}
}
}