cdk-rs icon indicating copy to clipboard operation
cdk-rs copied to clipboard

Please change syntax to be more noticeable

Open vporton opened this issue 1 year ago • 4 comments

Please, change the syntax from

#[update]
fn f(/*...*/) {
  // ...
}

to

#[update]
#[return_immediately]
fn f(/*...*/) {
  // ...
}

Give a warning if used old syntax.

This is because the first syntax deviates from the usual meaning of Rust functions (usual Rust functions never return before their body has finished executing) and can be too easily confused by a user with an async #[update] (or #[query]) function. This is just too much error-prone and the programmer needs to see that the function returns before its execution.

The current practice deviates from the sound Rust practice to be a reliable programming language.

vporton avatar Aug 13 '24 05:08 vporton

I don't understand this. Functions never return immediately. If you make an inter-canister call, it won't return until the function finishes. The behavior is exactly the same for async functions.

You may be referring to making update calls from the agent side. In that case, it's up to the caller to decide if you want to call the endpoints asynchronously or synchronously. If calling asynchronously, it yields the control, and the agent has to poll to get the result, and you won't get the result until the function returns. If calling synchronously, it waits until the functions returns. Again, this is entirely up to the caller to decide how they want to make the call, it has nothing to do with the canister endpoints.

chenyan-dfinity avatar Aug 13 '24 20:08 chenyan-dfinity

I don't understand this. Functions never return immediately. If you make an inter-canister call, it won't return until the function finishes. The behavior is exactly the same for async functions.

In Motoko, there are sync methods like this:

public shared func inc() : () { /*...*/ };

(note no async here). Such functions return immediately, before doing /.../ calculations (that may be done after the function returns).

It apparently translates to Rust as:

#[update]
func inc() { /*...*/ };

(note no async).

You may be referring to making update calls from the agent side. In that case, it's up to the caller to decide if you want to call the endpoints asynchronously or synchronously. If calling asynchronously, it yields the control, and the agent has to poll to get the result, and you won't get the result until the function returns. If calling synchronously, it waits until the functions returns. Again, this is entirely up to the caller to decide how they want to make the call, it has nothing to do with the canister endpoints.

This is unrelated.

vporton avatar Aug 13 '24 21:08 vporton

It apparently translates to Rust as:

#[update] func inc() { /.../ };

No, this is equivalent to public shared func inc() : async (). There is no one-way function attributes in Rust CDK.

chenyan-dfinity avatar Aug 13 '24 21:08 chenyan-dfinity

There is no one-way function attributes in Rust CDK.

I request it to be implemented.

vporton avatar Aug 14 '24 02:08 vporton

There is no one-way function attributes in Rust CDK.

I request it to be implemented.

oneway is not a general concept on IC. There is no mechanism to enforce an update/query entry point to be oneway.

However, a caller can choose to call an update/query method without waiting for the response.

Since ic-cdk v0.18, the new Call::oneway() API enables calling any canister methods without waiting for the response.

lwshang avatar Jun 04 '25 13:06 lwshang