32 个稳定版本 (7 个主要版本)

9.1.3 2023 年 6 月 21 日
8.0.1 2023 年 6 月 2 日
7.0.1 2023 年 5 月 26 日
6.0.2 2023 年 5 月 4 日
1.0.0 2020 年 5 月 16 日

#189 in 并发


用于 pptr

自定义许可

28KB
303

vin

轻量级、人体工程学且非常规的演员包。

Crates.io Documentation MIT licensed

[dependencies]
vin = "9.1"

概述

Vin 的目标是成为一个人体工程学且非常规的演员库。Vin 不遵循传统演员库的实现方式,而是尽可能地简单,同时通过尽可能多地与 tokio 集成,提供人体工程学且丰富的接口。每个演员都有自己的任务来轮询消息并执行处理器。其地址通过简单的 Arc 共享。Vin 还提供了一种优雅地关闭所有演员的方法,而无需自己进行手动劳动。演员数据存储在其演员上下文中,并可以通过 Actor::ctx() 读取和通过 Actor::ctx_mut() 编写,这些方法获取数据的 RwLock。Vin 还提供了一种“任务演员”,这只是一个由 tokio 启动并与 Vin 的关闭系统同步的任务。

Vin 完全依赖于 tokio(异步运行时)、log(诊断)和 async_trait

示例

常规演员

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;
}

任务演员

vin 中任务演员的基本使用。

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 许可 许可。

依赖

~4–11MB
~109K SLoC