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?

1 Like

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

Anyone knows what ic_cdk::api::cycles_burn function does?

I’m not a dev, and have not worked with the ic_cdk package/library.

Just read this code from Bob open-source in github and curious about how it works, whether the cycles are sent to a black-hole or some computation really occurs and burns the cycles!

let burned_cycles = ic_cdk::api::cycles_burn(cycles_per_round as u128) as u64;

Or in another line

let burned_cycles = ic_cdk::api::cycles_burn(max_cycles_per_round);

Thank you very much in advance for the time and help.