27 个稳定版本 (7 个主要版本)
8.0.2 | 2023年6月21日 |
---|---|
7.0.1 | 2023年6月2日 |
6.0.1 | 2023年5月26日 |
5.0.4 | 2023年3月24日 |
1.1.2 | 2022年11月2日 |
#5 in #vin
在 2 个crate中使用 (通过 vin)
37KB
736 代码行
vin
一个轻量级、易用且非常规的actor crate。
[dependencies]
vin = "9.1"
概述
Vin 的目标是成为一个易用、非常规的 actor 库。Vin 不遵循传统 actor 库的实现方式,而是尽可能简单,同时通过与尽可能多的 tokio
集成,提供易用且丰富的接口。每个 actor 都有自己的任务来轮询消息和执行处理器。其地址通过简单的 Arc
共享。Vin 还提供了一种优雅地关闭所有 actor 的方法,无需您手动操作。actor 数据存储在其 actor 上下文中,可以使用 Actor::ctx()
读取,使用 Actor::ctx_mut()
写入,这些方法会获取数据的 RwLock
。Vin 还提供了一种“任务 actor”,它只是一个与 Vin 的关闭系统同步的 tokio
任务。
Vin 完全依赖于 tokio
(异步运行时)、log
(诊断)和 async_trait
。
示例
常规 actor
vin
的基本使用。
use vin::prelude::*;
use std::time::Duration;
use tracing::Level;
#[vin::message]
#[derive(Debug, Clone)]
pub enum Msg {
Foo,
Bar,
Baz,
}
#[vin::message(result = u32, error = String)]
#[derive(Debug, Clone)]
pub struct MsgWithResult;
#[vin::actor]
#[vin::handles(Msg)]
struct MyActor {
pub number: u32,
}
#[async_trait]
impl vin::Hooks for MyActor {}
#[async_trait]
impl vin::Handler<Msg> for MyActor {
async fn handle(&self, msg: Msg) -> Result<(), ()> {
let ctx = self.ctx().await;
println!("The message is: {:?} and the number is {}", msg, ctx.number);
Ok(())
}
}
#[async_trait]
impl vin::Handler<MsgWithResult> for MyActor {
async fn handle(&self, MsgWithResult(should_err): MsgWithResult) -> Result<u32, String> {
if should_err { Err("error".to_string()) }
else { Ok(42) }
}
}
#[tokio::main]
async fn main() {
tracing_subscriber::fmt()
.with_max_level(Level::TRACE)
.init();
let ctx = VinContextMyActor { number: 42 };
let actor = MyActor::start("test", ctx).unwrap();
actor.send(Msg::Bar).await;
tokio::time::sleep(Duration::from_millis(500)).await;
let res = actor.send_and_wait(MsgWithResult(false)).await.unwrap();
assert_eq!(res, 42);
vin::shutdown();
vin::wait_for_shutdowns().await;
}
任务 actor
vin
中任务 actor 的基本使用。
use vin::*;
use std::time::Duration;
use tracing::Level;
#[vin::task]
#[derive(Debug, Clone, PartialEq, Eq)]
struct MyTaskActor {
pub number: u32,
}
#[async_trait]
impl vin::Task for MyTaskActor {
async fn task(self) -> anyhow::Result<()> {
for i in 0..self.number {
log::info!("{}. iteration", i);
}
Ok(())
}
}
#[tokio::main]
async fn main() {
tracing_subscriber::fmt()
.with_max_level(Level::TRACE)
.init();
let ctx = VinContextMyTaskActor { number: 5 };
let actor = MyTaskActor::start("test_task", ctx);
tokio::time::sleep(Duration::from_millis(100)).await;
actor.close();
vin::shutdown();
vin::wait_for_shutdowns().await;
}
许可协议
本项目采用 MIT 许可协议。
依赖项
~2MB
~44K SLoC