canic_core/ops/ic/
timer.rs1pub use crate::cdk::timers::TimerId;
2
3use crate::{
4 cdk::timers::{
5 clear_timer as cdk_clear_timer, set_timer as cdk_set_timer,
6 set_timer_interval as cdk_set_timer_interval,
7 },
8 model::metrics::{
9 system::{SystemMetricKind, SystemMetrics},
10 timer::{TimerMetrics, TimerMode},
11 },
12 ops::perf::PerfOps,
13 perf::perf_counter,
14};
15use std::{cell::RefCell, future::Future, rc::Rc, time::Duration};
16
17pub struct TimerOps;
22
23impl TimerOps {
24 pub fn set(
27 delay: Duration,
28 label: impl Into<String>,
29 task: impl Future<Output = ()> + 'static,
30 ) -> TimerId {
31 let label = label.into();
32
33 SystemMetrics::increment(SystemMetricKind::TimerScheduled);
34 TimerMetrics::ensure(TimerMode::Once, delay, &label);
35
36 cdk_set_timer(delay, async move {
37 TimerMetrics::increment(TimerMode::Once, delay, &label);
38
39 let start = perf_counter();
40 task.await;
41 let end = perf_counter();
42
43 PerfOps::record(&label, end.saturating_sub(start));
44 })
45 }
46
47 pub fn set_interval<F, Fut>(interval: Duration, label: impl Into<String>, task: F) -> TimerId
50 where
51 F: FnMut() -> Fut + 'static,
52 Fut: Future<Output = ()> + 'static,
53 {
54 let label = label.into();
55
56 SystemMetrics::increment(SystemMetricKind::TimerScheduled);
57 TimerMetrics::ensure(TimerMode::Interval, interval, &label);
58
59 let task = Rc::new(RefCell::new(task));
60
61 cdk_set_timer_interval(interval, move || {
62 let label = label.clone();
63 let interval = interval;
64 let task = Rc::clone(&task);
65
66 async move {
67 TimerMetrics::increment(TimerMode::Interval, interval, &label);
68
69 let start = perf_counter();
70 let fut = { (task.borrow_mut())() };
71 fut.await;
72 let end = perf_counter();
73
74 PerfOps::record(&label, end.saturating_sub(start));
75 }
76 })
77 }
78
79 pub fn clear(id: TimerId) {
81 cdk_clear_timer(id);
82 }
83}