Skip to content

Commit

Permalink
feat: provide safe wrapper of global_timer_set in ic-cdk (#475)
Browse files Browse the repository at this point in the history
* feat: provide safe wrapper of global_timer_set in ic-cdk

* changelog

* e2e test
  • Loading branch information
lwshang authored Mar 29, 2024
1 parent ab458c4 commit a47fd6d
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 0 deletions.
5 changes: 5 additions & 0 deletions e2e-tests/canisters/timers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,9 @@ fn add_event(event: &'static str) {
EVENTS.with(|events| events.borrow_mut().push(event));
}

#[update]
fn set_global_timer(timestamp: u64) -> u64 {
ic_cdk::api::set_global_timer(timestamp)
}

fn main() {}
33 changes: 33 additions & 0 deletions e2e-tests/tests/e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,39 @@ fn advance_seconds(env: &StateMachine, seconds: u32) {
}
}

#[test]
fn test_set_global_timers() {
// Must be more than the queue limit (500)
let env = env();
let system_time = std::time::SystemTime::now();

env.set_time(system_time);

let wasm = cargo_build_canister("timers");
let canister_id = env.create_canister(None);
env.install_canister(canister_id, wasm, vec![], None);

call_candid::<_, ()>(&env, canister_id, "schedule_long", ())
.expect("Failed to call schedule_long");
let ts0 = system_time
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos() as u64
+ 9_000_000_000; // the long event is scheduled 9 seconds from ts0
advance_seconds(&env, 5);

// set the timer to 5 seconds from ts0
let ts1 = ts0 + 5_000_000_000;
let (previous,) = call_candid::<(u64,), (u64,)>(&env, canister_id, "set_global_timer", (ts1,))
.expect("Failed to call set_global_timer");
assert_eq!(previous, ts0);

// deactivate the timer
let (previous,) = call_candid::<(u64,), (u64,)>(&env, canister_id, "set_global_timer", (0,))
.expect("Failed to call set_global_timer");
assert_eq!(previous, ts1);
}

#[test]
fn test_canister_info() {
let env = env();
Expand Down
4 changes: 4 additions & 0 deletions src/ic-cdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [unreleased]

### Added

- Provide safe wrapper of global_timer_set in ic-cdk. (#475)

## [0.13.1] - 2024-03-01

### Changed
Expand Down
17 changes: 17 additions & 0 deletions src/ic-cdk/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,20 @@ pub fn cycles_burn(amount: u128) -> u128 {
}
dst
}

/// Sets global timer.
///
/// The canister can set a global timer to make the system
/// schedule a call to the exported canister_global_timer
/// Wasm method after the specified time.
/// The time must be provided as nanoseconds since 1970-01-01.
///
/// The function returns the previous value of the timer.
/// If no timer is set before invoking the function, then the function returns zero.
///
/// Passing zero as an argument to the function deactivates the timer and thus
/// prevents the system from scheduling calls to the canister's canister_global_timer Wasm method.
pub fn set_global_timer(timestamp: u64) -> u64 {
// SAFETY: ic0.global_timer_set is always safe to call.
unsafe { ic0::global_timer_set(timestamp as i64) as u64 }
}

0 comments on commit a47fd6d

Please sign in to comment.