Asynchronous Deferred Calls
This crate implements the Active Object design pattern.
The entry point of this crate is [Dispatcher], which wraps an Arc<Lock<T>>.
Note: Lock can be RwLock or Mutex from the async-lock crate.
[Dispatcher]
The [Dispatcher] allows you to create [Caller]s for some methods on T.
You can then schedule deferred calls to these methods via these [Caller]s.
[Dispatcher] implements Future; You must await this future for calls to
actually be dispatched.
[Caller]
When you create a [Caller] for a method of T using [Dispatcher], a background
task is created, waiting for you to schedule deferred calls via the [Caller]. When
a call is scheduled, the background task will lock the RwLock or Mutex and call
the method on the locked T instance.
Compatible T methods
The methods must:
- be asynchronous
- return an implementer of [
ReturnType]
They can take self mutably or immutably.
Note: you can use a freestanding function instead of a method if the first parameter
of that function is &T or &mut T.
[Summoner]
if the method's last parameter is an [async_channel::Sender], you can turn your [Caller] into
a [Summoner], which makes it easy to wait for a reply when you schedule a call.
Example
use ;
use ;
use Arc;
// An example object which will be modified in deferred calls
;
let world = new;
let mut dispatcher = new;
let deferred_print = dispatcher.listen_mut_1;
let deferred_ping_pong = dispatcher.listen_ref_2;
async ;
In this example, two background tasks are created, one for each method of Subject.
The ping_pong method's last parameter is a Sender, allowing us to "summon" the method.