@christian exposed call_raw* and arg_data_raw functions. This API allows you to call canisters that do not encode their arguments as Candid or forward calls without decoding the payload.
@roman-kashitsyn added notify* family of functions relying on the trick that @nomeata described in his blog post. If your canister uses onlynotify* calls, it safe to upgrade the canister without stopping it first. The notify is a regular call setting a non-existing function as a callback. One practical implication of that implementation is that you get a refund if you attach cycles to the notification and the destination canister traps.
Enjoy building on the IC with the improved Rust CDK!
@roman-kashitsyn added notify* family of functions relying on the trick that @nomeata described in his blog post . If your canister uses onlynotify* calls, it safe to upgrade the canister without stopping it first. The notify is a regular call setting a non-existing function as a callback. One practical implication of that implementation is that you get a refund if you attach cycles to the notification and the destination canister traps.
Very exciting! Do you happen to know if and when Motoko will support the same thing?
Actually, I don’t think that’s correct. The shared function needs to be declared as a oneway function (returning (), not async ()) and just called without an await.
So, for this example:
Actor:
actor canister_a {
// `()` return declares a Candid oneway function that can't be awaited.
public shared func method() : () {
...
};
}
Client:
canister_a.method(); // no `await` possible (given return type of `()`, not `async ()`)
I think I would call it the exact opposite of elegant. It takes advantage of the fact that WASM is single-threaded to use global state. Essentially, it sets a global bool, executes the future, and then unsets it; the executor, when asked to execute a future, checks the global bool, and if it is set then it doesn’t actually execute the future but simply drops it.
The behavior is that all destructors are run in the case of an inter-canister trap, but execution does not continue. You can attach custom cleanup logic by placing it in a destructor via a crate like scope_guard.