use crate::types::DurationNanos;
#[inline]
pub fn async_execute<Task>(task: Task) -> ic_cdk_timers::TimerId
where
Task: FnOnce() + 'static,
{
ic_cdk_timers::set_timer(std::time::Duration::ZERO, task)
}
pub use ic_cdk_timers::TimerId;
pub trait Schedulable {
fn schedule_find(&self) -> Option<DurationNanos>;
fn schedule_replace(&mut self, schedule: Option<DurationNanos>);
}
#[inline]
pub fn schedule_stop(timer_id: Option<TimerId>) {
if let Some(timer_id) = timer_id {
ic_cdk_timers::clear_timer(timer_id)
}
}
#[inline]
pub fn schedule_start(
schedule: &Option<DurationNanos>,
task: impl FnMut() + 'static,
) -> Option<TimerId> {
schedule.map(|interval| {
ic_cdk_timers::set_timer_interval(
std::time::Duration::from_nanos(interval.into_inner() as u64),
task,
)
})
}
pub mod basic {
use candid::CandidType;
use serde::{Deserialize, Serialize};
use crate::{functions::types::Schedulable, types::DurationNanos};
#[cfg(feature = "schedule")]
mod schedule {
use std::cell::RefCell;
use ic_cdk_timers::TimerId;
use crate::types::DurationNanos;
thread_local! {
static SCHEDULE: RefCell<Option<TimerId>> = RefCell::default(); }
#[inline]
pub fn stop_schedule() {
SCHEDULE.with_borrow_mut(|timer_id| {
crate::functions::schedule::schedule_stop(std::mem::take(timer_id))
});
}
#[inline]
pub fn start_schedule(schedule: &Option<DurationNanos>, task: impl FnMut() + 'static) {
stop_schedule();
let new_timer_id = crate::functions::schedule::schedule_start(schedule, task);
SCHEDULE.with_borrow_mut(|timer_id| *timer_id = new_timer_id);
}
}
#[cfg(feature = "schedule")]
pub use schedule::*;
#[derive(CandidType, Serialize, Deserialize, Debug, Clone, Default)]
pub struct Schedule(Option<DurationNanos>);
impl Schedulable for Schedule {
fn schedule_find(&self) -> Option<DurationNanos> {
self.0
}
fn schedule_replace(&mut self, schedule: Option<DurationNanos>) {
self.0 = schedule
}
}
}
#[cfg(feature = "schedule")]
pub use basic::{start_schedule, stop_schedule};