Some questions about the timer in ic-cdk

I found that there are three main functions in the timer mod, set_timer, set_timer_interval, clear_timer. Among them, set_timer is used to set a one-time task, set_timer_interval is used to set a periodic task, and clear_timer is used to cancel a one-time task/periodic task.

  1. Since set_timer is a one-time task, why not automatically delete TimerId after the task is completed? If a large amount of TimerId produced by set_timer accumulates, will it affect the performance of the canister or the consumption of cycles? for example:
#[update]
fn again() {
    set_timer_interval(Duration::from_secs(10), || {
        ic_cdk::print("0");
        set_timer(Duration::from_secs(1), || {
            ic_cdk::print("1");
            set_timer(Duration::from_secs(1), || {
                ic_cdk::print("2");
                set_timer(Duration::from_secs(1), || {
                    ic_cdk::print("3");
                    set_timer(Duration::from_secs(1), || {
                        ic_cdk::print("4");
                    });
                });
            });
        });
    });
}

I need to execute 5 tasks sequentially every 10 seconds. In this way, a large number of TimerId will be generated after a period of time.
2. Can periodic tasks be terminated by task itself? Currently, periodic tasks set by set_timer_interval can be terminated only by manually calling clear_timer. Can periodic tasks be terminated automatically when certain conditions are met in the task?

Since set_timer is a one-time task, why not automatically delete TimerId after the task is completed?

That’s exactly what’s happening. For one-off timers you need the timer id just to cancel the timer before the deadline.

Can periodic tasks be terminated by task itself?

For that we need to build some logic on top… Please also note, the CDK does not handle canister upgrades, and some custom logic has to be implemented in pre- and post-upgrade methods. So, in many case it’s probably a good idea to store somewhere pending timers, and serialize/deserialize them on canister upgrade.

The timers API is not set in stone, and since the functionality is implemented in CDK, changing this API is not a breaking change for the canisters running on the mainnet… Any suggestions or third-party abstractions on top of the CDK are very welcome!

4 Likes