Async* await* Does this do what I think it does?

This is what I use locally to call things that I don’t want to actually wait on a round?

private func _x(y : Nat) : async* Nat{
     y*2
};

public shared(msg) func x(y: Nat) : async Nat{
     await* _x(y);
};

Can async* functions themselves have awaits inside of them?

private func _x(y : Nat) : async* Nat {
     switch(Map.get<Nat, Nat>(my_cache, y){
           case(null){
                let remote_result = await other_actor.calc(y);
                Map.set<Nat,Nat>(my_cache, y, remote_result);
           };
           case(?val){val};
     };
};

public shared(msg) func x(y: Nat) : async Nat{
     await* _x(y);
};

Does await now “Always” wait a round of consensus?

When will 0.7.4 make it into dfx for use?

0.7.4 will be in the next release, a beta version is planned for today or early next week.

1 Like

If I want dfx build to use the latest (0.7.6) motoko, what do I need to do? I’m also using vessel:

"defaults": {
    "build": {
      "args": "",
      "packtool": "vessel sources"
    },
    "replica": {
      "subnet_type": "system"
    }
  },

Where do I need to put vessel? Do I need to download moc as well? Where do I put that?

1 Like

Here’s how to use a different Motoko version: DFX deploy with custom Motoko version

Anywhere in your $PATH.

vessel does it for you.

I ended up having to put moc into the cache/dfx0.12.1/ folder and give it execute.

Maybe I should be calling something other than dfx build? Or maybe I should have installed a beta version of dfx and I would have gotten this for free?

I thought of replacing moc in the cache folder but thought it’s a bit too hacky to recommend. It works quite well, you just have to think of doing it again if you ever change dfx versions.

If you build using a canister of type motoko, then setting the env var is probably the cleanest. You can also export that one in your .bashrc or some other dotfile if you want it globally.

No, it’s not in a beta version yet. The dfx beta that just released still only contains 0.7.4.

Set compiler version to “0.7.6” in vessel.dhall file and download the compiler with
vessel verify --version 0.7.6 and then pass it to dfx:
DFX_MOC_PATH="$(vessel bin)/moc" dfx build <canister_name>

1 Like

Is there an example of when specifically using an async* declaration could cause conflicts in concurrent access to state between callers, as opposed to a standard async declaration (that wouldn’t)?

Very exciting feature to have as part of Motoko.

I don’t think async* changes access to state semantics, but I’ll ask the Motoko team as well.

1 Like

An await*-ed async* expression will only yield control to the scheduler/allow interleaving if its body directly (or any async* that it await*s) does a proper, old fashioned await.

So think of the * as this may do 0 or more awaits. If 0, there is not possibility of concurrent interaction. If 1 or more, you need to be careful. If you don’t know how many, you need to be conservative and careful and avoid leaving any shared state (visible by other concurrent calls) in an inconsistent state.

3 Likes