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日 |
#934 在 Rust 模式
每月102次下载
50KB
532 行
Messages. 方便的异步通信
描述
messages
是一个跨运行时的演员库。
它受到了伟大的演员框架 actix
的极大启发。
这个包可以与任何运行时一起使用,无论它是否受欢迎。然而,对于最大的一个(tokio 和
async-std
),有一个可选的内置支持,它提供更方便的接口(例如自动演员创建)。
主要功能
- 完全的运行时独立性。可以与任何可以创建未来的可能运行时一起使用。
- 低依赖量。
- 无需 derive 宏的少量样板代码。
- 良好的性能(接近原始通道)。
- 相关但足够的功能。
我应该选择哪个库?
actix
是一个优秀、深思熟虑、精心打磨且优化的库。如果可能的话,你应该将其作为主要选项考虑。
然而,如果你使用以下任何一种情况,messages
可能更好
- 你不能或不想坚持 Actix 运行时。
- 你的任务可能不具有类似的运行时开销(
actix-rt
没有工作窃取,因此在这种情况下某些线程可能会过载)。 - 你正在寻找更简单的接口,并且不想在最初是同步接口之上实现异步代码。
但关于xactor
怎么办呢?
xactor
是受Actix启发的另一个优秀的库。最初它是为async-std
构建的,但后来增加了对tokio
的支持。
尽管如此,这个库并不是运行时无关的。它支持async-std
和tokio
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-std
:Notify
示例的async-std
运行时版本。smol
:使用未直接支持的运行时的示例。在这种情况下,使用smol
。- WebSocket:基于actor的简单echo websocket服务器(以及一个用于玩耍的客户端)。
贡献
非常欢迎各种形式的贡献!
许可协议
messages
库采用MIT许可协议。有关详细信息,请参阅LICENSE。
依赖项
~1-15MB
~147K SLoC