speare
speare
is a minimalistic actor framework that also has pub / sub capabities.
Your first Process
speare
revolves around the idea of Processes
, which have their states isolated to their own tokio::task
.
Processes need to implement the Process
trait. To define message handlers you can use the #[process]
and #[handler]
attributes.
use *;
;
Arguments for functions with the #[handler]
attribute should always be: &mut self
, msg: M
, ctx: &Ctx<Self>
.
After defining your Process
, you can now spawn it in a Node
and send a fire and forget message with .tell()
, or wait for a response with .ask()
.
async
Processes
can also have custom behaviour on startup and on termination.
If you need to send messages or spawn other processes from inside a Process
, you can do so using the Ctx<Self>
reference, which also has all functions availalbe on a Node
instance.
To terminate a process you can use the .exit()
function.
let node = default;
let counter_pid = node.spawn.await;
node.exit.await;
The Reply
type
Every #[handler]
must return a Reply<T,E>
, which is just an alias for Result<Option<T>, E>
. You can still use ?
to early return errors from your #[handler]
functions. There are two helper functions for creating Replies:
noreply()
will make it impossible for .ask()
to succeed on that specific handler, unless an instance of a Responder
is stored somewhere.
Deferring Replies
To avoid replying immediately or even in the same #[handler]
that receives a message, you can use noreply()
on the original #[handler]
, and store the responder for that message to send the response later. If the Responder
is not stored and noreply()
is used, calling .ask()
on that #[handler]
will always fail. In the example below you can see Dog
will only reply to SayHi
once it is given a bone with the GiveBone
message.
use *;
;
;
Pub / Sub
Every Process
that implements a Handler
for a message M
, can also manually subscribe to global publishes of that message, the only requirement being that the message must implement Clone
.
Here is a small example:
use *;
;
;
;
async