23个版本
0.1.10 | 2024年4月29日 |
---|---|
0.1.9 | 2024年4月29日 |
0.1.8 | 2024年1月21日 |
0.0.12 | 2023年11月23日 |
0.0.2 | 2023年10月9日 |
#325 in 异步
50KB
793 行
speare
speare
是一个极简的actor框架。在tokio任务和flume通道之上的薄抽象,灵感来源于Akka.NET。阅读The Speare Book以获取有关如何使用库的更多详细信息。
快速查看
以下是一个非常极简的Counter
Process
示例。
use speare::*;
use async_trait::async_trait;
use tokio::time;
struct Counter {
count: u32,
}
enum CounterMsg {
Add(u32),
Subtract(u32),
Print
}
#[async_trait]
impl Process for Counter {
type Props = ();
type Msg = CounterMsg;
type Err = ();
async fn init(ctx: &mut Ctx<Self>) -> Result<Self, Self::Err> {
Ok(Counter { count: 0 })
}
async fn handle(&mut self, msg: Self::Msg, ctx: &mut Ctx<Self>) -> Result<(), Self::Err> {
match msg {
CounterMsg::Add(n) => self.count += n,
CounterMsg::Subtract(n) => self.count -= n,
CounterMsg::Print => println!("Count is {}", self.count)
}
Ok(())
}
}
#[tokio::main]
async fn main() {
let mut node = Node::default();
let counter = node.spawn::<Counter>(());
counter.send(CounterMsg::Add(5));
counter.send(CounterMsg::Subtract(2));
counter.send(CounterMsg::Print); // will print 3
// We wait so the program doesn't end before we print.
time::sleep(Duration::from_millis(1)).await;
}
为什么选择speare
?
speare
是在tokio绿色线程和flume通道之上的最小抽象层,提供管理这些线程和在这些线程之间以更实用方式传递消息的功能。相反,应该问的是: "为什么是消息传递(通道)而不是共享状态(例如 Arc<Mutex<T>>
)?"
- 更容易推理:使用消息传递,每次只有一个线程拥有数据的一部分,这使得数据的流动和控制更容易推理。
- 避免死锁:带有锁(如互斥锁)的共享状态如果不小心管理,可能会导致死锁。在Rust中,消息传递(特别是消息传递)不太可能导致死锁,因为它不涉及传统的锁定机制。
- 鼓励解耦设计:消息传递促进了更模块化和解耦的设计,其中组件通过定义良好的接口(通道)进行通信,提高了代码的可维护性和可扩展性。
常见问题解答
speare
有多快?
我还没有对最新版本进行基准测试,也没有进行任何性能优化。发送消息时存在装箱的开销,但总体来说,它相当快。基准测试待定,并将在此处添加。
它是否已准备好用于生产?
还不是!但很快了 :-)
为什么我应该使用这个而不是其他3000亿个Rust actor框架?
我构建speare
是因为我想有一个非常极简的actor框架,只提供足够的抽象来抽象tokio绿色线程和通道,而不引入大量的样板代码或许多新概念给我的同事。如果您喜欢它的设计,请使用speare
;如果不喜欢的化,那就不要用 :-)
我能贡献吗?
当然可以!只有两条规则需要遵守
- 要有礼貌
- 不要变成一个混蛋
请记住,我希望保持这个项目的极简主义,但我非常欢迎建议和新想法 :)
依赖项
~2.4–4MB
~67K SLoC