8 个不稳定版本 (3 个破坏性更新)

0.4.0 2022年12月12日
0.3.0 2022年12月11日
0.2.0 2022年12月9日
0.1.4 2022年12月7日

#1230 in 异步

Download history 51/week @ 2024-03-11 16/week @ 2024-03-18 23/week @ 2024-03-25 41/week @ 2024-04-01 8/week @ 2024-04-08 12/week @ 2024-04-15 13/week @ 2024-04-22 8/week @ 2024-04-29 12/week @ 2024-05-06 14/week @ 2024-05-13 19/week @ 2024-05-20 23/week @ 2024-05-27 10/week @ 2024-06-03 14/week @ 2024-06-10 10/week @ 2024-06-17 19/week @ 2024-06-24

55 每月下载次数
6 个 crate 使用 (直接使用2个)

MIT 许可证

13KB
187 代码行

Puppet - 一个简单的actor框架

Puppet 是一个不使用装箱或动态调度项的actor框架,它使用一个小宏来生成基于枚举的系统模板代码。

特性

  • 泛型感知,这意味着您可以让泛型actor返回泛型消息。
  • 无装箱,不需要 async_trait 或装箱进行动态调度。
  • 代码检查器友好,您的编辑器应该能够轻松推断出所有公开方法的返回类型。
  • 同步和异步邮箱方法。

基本示例

让我们创建一个小的actor来创建hello消息...

use puppet::{puppet_actor, ActorMailbox, Message};

pub struct MyActor;

#[puppet_actor]
impl MyActor {
    #[puppet]
    async fn on_say_hello(&self, msg: SayHello) -> String {
        format!("Hello, {}!", msg.name)
    }
}

pub struct SayHello {
    name: String
}
impl Message for SayHello {
    type Output = String;
}

#[tokio::main]
async fn main() {
    // Create the actor.
    let actor = MyActor;
    
    // Spawn it on the current runtime, which returns to us a mailbox which
    // we can use to communicate with the actor.
    let mailbox: ActorMailbox<MyActor> = actor.spawn_actor().await;

    let message = SayHello {
        name: "Harri".to_string(),
    };
    
    // Send a message to the actor and wait for a response.
    let response = mailbox.send(message).await;
    println!("Got message back! {}", response);
}

泛型示例

如果我们想用actor做一些更高级的事情呢?幸运的是,我们可以使用泛型。

use puppet::{puppet_actor, ActorMailbox, Message};

pub struct AppenderService<T: Clone> {
    seen_data: Vec<T>,
}

#[puppet_actor]
impl<T> AppenderService<T>
where
    // The additional `Send` and `'static` bounds are required due to the nature
    // of the actor running as a tokio task which has it's own requirements.
    T: Clone + Send + 'static,
{
    fn new() -> Self {
        Self {
            seen_data: Vec::new(),
        }
    }

    #[puppet]
    async fn on_append_and_return(&mut self, msg: AppendAndReturn<T>) -> Vec<T> {
        self.seen_data.push(msg.value);
        self.seen_data.clone()
    }
}

#[derive(Clone)]
pub struct AppendAndReturn<T: Clone> {
    value: T,
}
impl<T> Message for AppendAndReturn<T>
where
    T: Clone,
{
    type Output = Vec<T>;
}

#[tokio::main]
async fn main() {
    let actor = AppenderService::<String>::new();
    let mailbox: ActorMailbox<AppenderService<String>> = actor.spawn_actor().await;

    let message = AppendAndReturn {
        value: "Harri".to_string(),
    };

    for _ in 0..3 {
        let response = mailbox.send(message.clone()).await;
        println!("Got values: {:?}", response);
    }
}

依赖项

~2.5–4MB
~83K SLoC