wasmCloud/wascc-host

Support asynchronous actor calls (Add a cast function)

autodidaddict opened this issue · 0 comments

waSCC should support the ability for actors to perform asynchronous host calls to either capability providers or to other actors. This will require making a little bit of change to the core dispatch system to allow for a new, short-lived thread to be spawned to handle the asynchronous activity because the actor's SDK asynchronous function should appear to the actor as a synchronous call that returns (almost) immediately with a return type of Result<()>.

Today, synchronous calls are made like this:

provider_module::binding().call(...)?;
// e.g.
messaging::default().request(..., ... )?;

The new asynchronous form will look like this:

provider_module::binding().cast(...)
// e.g.
messaging::default().publish_async(..., ...)?;

The cast function in the SDK will be responsible for creating an invocation passed up to the host that will have some kind of async indicator on it, which will tell the host to spawn the dispatch in a short-lived thread and ignore the result, returning control immediately to the actor.

Caveats
With the ability to perform a cast, actors will be able to free up their queue drain/work intake faster, and will even be able to support cyclic call patterns. This, of course, means that it is now the responsibility of the developer to avoid getting an actor into an infinite call loop, which could effectively DDoS multiple waSCC hosts simultaneously. Developers should not hope for or assume any kind of loop detection and correction functionality in the host.

Similarly, we can add a new function to the WasccHost called cast to complement the existing cast function that will spawn a short-lived thread, perform the dispatch, and ignore the result.

This functionality will continue to work whether running in isolation or as part of a lattice. If multiple instances of the same target exist, then one of them will be chosen at random for the asynchronous execution the same way they're chosen for synchronous execution.

Bibliography
The call/cast naming and behavioral convention is inspired directly from patterns in use in Elixir/Erlang when dealing with OTP.