diff --git a/spec/_attachments/ic.did b/spec/_attachments/ic.did index 717fd680..a1ddfe46 100644 --- a/spec/_attachments/ic.did +++ b/spec/_attachments/ic.did @@ -14,6 +14,7 @@ type canister_settings = record { reserved_cycles_limit : opt nat; log_visibility : opt log_visibility; wasm_memory_limit : opt nat; + wasm_memory_threshold : opt nat; }; type definite_canister_settings = record { @@ -24,6 +25,7 @@ type definite_canister_settings = record { reserved_cycles_limit : nat; log_visibility : log_visibility; wasm_memory_limit : nat; + wasm_memory_threshold: nat; }; type change_origin = variant { diff --git a/spec/index.md b/spec/index.md index ab073186..715a51ad 100644 --- a/spec/index.md +++ b/spec/index.md @@ -1218,6 +1218,8 @@ In order for a WebAssembly module to be usable as the code for the canister, it - If it exports a function called `canister_heartbeat`, the function must have type `() -> ()`. +- If it exports a function called `canister_on_low_wasm_memory`, the function must have type `() -> ()`. + - If it exports a function called `canister_global_timer`, the function must have type `() -> ()`. - If it exports any functions called `canister_update `, `canister_query `, or `canister_composite_query ` for some `name`, the functions must have type `() -> ()`. @@ -1271,6 +1273,8 @@ The canister provides entry points which are invoked by the IC under various cir - The canister may export functions with name `canister_composite_query ` and type `() -> ()`. +- The canister may export functions with name `canister_on_low_wasm_memory` and type `() -> ()`. + - The canister table may contain functions of type `(env : i32) -> ()` which may be used as callbacks for inter-canister calls and composite query methods. If the execution of any of these entry points traps for any reason, then all changes to the WebAssembly state, as well as the effect of any externally visible system call (like `ic0.msg_reply`, `ic0.msg_reject`, `ic0.call_perform`), are discarded. For upgrades, this transactional behavior applies to the `canister_pre_upgrade`/`canister_post_upgrade` sequence as a whole. @@ -1348,6 +1352,18 @@ While an implementation will likely try to keep the interval between the value o ::: +#### On Low Wasm Memory {#on-low-wasm-memory} + +A canister can export a function with the name `canister_on_low_wasm_memory`, which is scheduled whenever the canister's remaining wasm memory size in bytes falls from above a threshold `t` to < `t`. +The threshold `t` can be defined in the [canister's settings](#ic-canister_status) and by default it is set to 0. + +:::note + +While the above function is scheduled immediately once the condition above is triggered, it may not necessarily be executed immediately if it does not have enough cycles. +If the canister gets frozen immediately after the function is scheduled for execution, the function will run once the canister's unfrozen _if_ the canister's wasm memory remains above the threshold `t`. + +::: + #### Callbacks Callbacks are addressed by their table index (as a proxy for a Wasm `funcref`). @@ -1485,7 +1501,7 @@ The comment after each function lists from where these functions may be invoked: - `F`: from `canister_inspect_message` -- `T`: from *system task* (`canister_heartbeat` or `canister_global_timer`) +- `T`: from *system task* (`canister_heartbeat` or `canister_global_timer` or `canister_on_low_wasm_memory`) - `*` = `I G U RQ NRQ CQ Ry Rt CRy CRt C CC F T` (NB: Not `(start)`) @@ -2228,6 +2244,8 @@ Indicates various information about the canister. It contains: - The WASM heap memory limit of the canister in bytes (the value of `0` means that there is no explicit limit). + - The "low wasm memory" threshold, which is used to determine when the [canister_on_low_wasm_memory](#on-low-wasm-memory) function is executed. + - A SHA256 hash of the module installed on the canister. This is `null` if the canister is empty. - The actual memory usage of the canister.