4 releases
0.2.0 | Nov 27, 2024 |
---|---|
0.1.3 | Nov 26, 2024 |
0.1.2 | Nov 20, 2024 |
0.1.1 | Sep 19, 2024 |
0.1.0 |
|
#540 in Asynchronous
537 downloads per month
19KB
529 lines
Pupactor is actor model library built with tokio
Macros and traits could help you to organise actors to look same
Actor body looks like:
#[derive(Pupactor)]
#[actor(cmd = "MyActorShutdown")]
struct MyFirstTestActor {
some_data: bool,
some_other_data: usize,
#[listener]
interval: Listener<Interval, Instant>,
#[listener]
interval2: Listener<Interval, Instant>,
#[listener]
channel: Listener<UnboundedReceiver<ActorMsg<Value, MyActorShutdown>>, Value, MyActorShutdown>,
}
where Pupactor
macro generates select!
macro that listens interval
, interval2
and channel
On each income event (Interval
, Value
) we need create a Handle like this:
impl AsyncHandle<Instant> for MyFirstTestActor {
async fn async_handle(&mut self, _value: Instant) {
self.some_other_data += 1;
println!("New msg, counter: {}", self.some_other_data);
}
}
Or sync handle if you do not need async
impl Handle<Instant> for MyFirstTestActor {
fn handle(&mut self, _value: Instant) {
self.some_other_data += 1;
println!("New msg, counter: {}", self.some_other_data);
}
}
For more complex values like enums, there is other macro ActorMsgHandle
:
#[derive(ActorMsgHandle)]
#[actor(kind = "MyFirstTestActor")]
pub enum Value {
MyGreetings(String),
U32(u32),
U64(u64),
}
So you will need describe handles only for String
, u32
and u64
impl AsyncHandle<u32> for MyFirstTestActor {
async fn async_handle(&mut self, value: u32) -> Continue {
println!("New msg: {value}");
}
}
All handles can return something. All return types:
Continue - actor continue live
Cmd<T> where T is MyActorShutdown - this is your custom command
Break - this command will break the infinite loop { select!{ ... } }
Resut<Continue, Cmd<T>>
Resut<Continue, Break>
Resut<Continue, Result<Break, Cmd<T>>>
Dependencies
~3–11MB
~109K SLoC