6 个版本

0.3.1 2022年1月21日
0.3.0 2021年6月16日
0.2.4 2021年6月6日
0.1.2 2020年8月4日

#934Rust 模式

Download history 1/week @ 2024-05-11 23/week @ 2024-05-18 2/week @ 2024-06-01 102/week @ 2024-07-27

每月102次下载

MIT 许可证

50KB
532

Messages. 方便的异步通信

状态: CI

项目信息: Docs.rs 最新版本 许可证 Rust 1.50+ 需要

描述

messages 是一个跨运行时的演员库。

它受到了伟大的演员框架 actix 的极大启发。

这个包可以与任何运行时一起使用,无论它是否受欢迎。然而,对于最大的一个(tokioasync-std),有一个可选的内置支持,它提供更方便的接口(例如自动演员创建)。

主要功能

  • 完全的运行时独立性。可以与任何可以创建未来的可能运行时一起使用。
  • 低依赖量。
  • 无需 derive 宏的少量样板代码。
  • 良好的性能(接近原始通道)。
  • 相关但足够的功能。

我应该选择哪个库?

actix 是一个优秀、深思熟虑、精心打磨且优化的库。如果可能的话,你应该将其作为主要选项考虑。

然而,如果你使用以下任何一种情况,messages 可能更好

  • 你不能或不想坚持 Actix 运行时。
  • 你的任务可能不具有类似的运行时开销(actix-rt 没有工作窃取,因此在这种情况下某些线程可能会过载)。
  • 你正在寻找更简单的接口,并且不想在最初是同步接口之上实现异步代码。

但关于xactor怎么办呢?

xactor是受Actix启发的另一个优秀的库。最初它是为async-std构建的,但后来增加了对tokio的支持。

尽管如此,这个库并不是运行时无关的。它支持async-stdtokio v1,但尚不支持其他运行时。

话虽如此,messages最初有不同用途:提供一个在不考虑支持的运行时的情况下实现actor工作流程的方法。

异步性

这个库以异步为首要,意味着一切都是按照异步架构制作的。虽然在某些情况下,同步接口可能更有性能,但它会使接口变得非常庞大。如果您更喜欢同步actor接口,可以考虑使用actix,因为它提供了这样的接口。

性能

简而言之:这个库提供的性能优于actix(对于异步消息处理;基于actix本身使用的环基准测试)并且与futures通道相关。

更详细的信息请参见BENCHES.md

注意:messages将异步和多线程上下文视为其主要环境,因此它可能不适合(或者更确切地说,效率较低)部分同步上下文。例如,同步版本的环基准测试比这个库快80%。

示例

有运行时功能

use messages::prelude::*;

struct Example; // Most of the types can be an actor.

// While `Actor` implementation can be customized, it is not required.
#[async_trait]
impl Actor for Example {}

// Message handler that calculated sum of two numbers.
#[async_trait]
impl Handler<(u8, u8)> for Example {
    type Result = u16;
    async fn handle(&mut self, (a, b): (u8, u8), context: &Context<Self>) -> u16 {
        (a as u16) + (b as u16)
    }
}

// Notification handler that calculated just writes received number to stdout.
#[async_trait]
impl Notifiable<u8> for Example {
    async fn notify(&mut self, input: u8, context: &Context<Self>) {
        println!("Received number {}", input);
    }
}

#[tokio::main]
async fn main() {
   let mut addr = Example.spawn();
   let result = addr.send((22, 20)).await.unwrap();
   assert_eq!(result, 42);
   addr.notify(42).await.unwrap();
   addr.stop().await;
   addr.wait_for_stop().await;  
}

无运行时功能

use messages::prelude::*;

struct Ping;

#[async_trait]
impl Actor for Ping {}

#[async_trait]
impl Handler<u8> for Ping {
    type Result = u8;
    async fn handle(&mut self, input: u8, context: &Context<Self>) -> u8 {
        input
    }
}

#[tokio::main]
async fn main() {
   let context = Context::new();
   let mut addr = context.address();
   let actor = Ping;
   // Could've been any other runtime.
   let mut task_handle = tokio::spawn(context.run(actor));
   let result = addr.send(42).await.unwrap();
   assert_eq!(result, 42);
   addr.stop().await;
   addr.wait_for_stop().await;
   task_handle.await.unwrap();
}

更多

更多示例可以在examples目录中找到。

它们编号并编写的方式是,下一个示例总是比上一个示例略好。您可以考虑它是一个暂时的替代书籍(稍后将会推出)。

当前提供示例列表

  • Ping:功能简单的ping actor。
  • Notify:更详细的示例,展示了actor接口的能力。
  • Fibonacci:协程actor的示例,即可以并行处理消息的actor。
  • Ring:环基准测试,大部分是从相应的actix示例中复制而来的。
  • Timed stream:示例展示了如何将流附加到actor,并向其发送定时通知。
  • async-stdNotify示例的async-std运行时版本。
  • smol:使用未直接支持的运行时的示例。在这种情况下,使用smol
  • WebSocket:基于actor的简单echo websocket服务器(以及一个用于玩耍的客户端)。

贡献

非常欢迎各种形式的贡献!

许可协议

messages库采用MIT许可协议。有关详细信息,请参阅LICENSE

依赖项

~1-15MB
~147K SLoC