3个不稳定版本

0.2.1 2020年3月13日
0.2.0 2020年3月5日
0.1.0 2020年3月4日

#197 in #router

每月35次下载

MIT许可证

64KB
433 代码行

herbert

Herbert是一个基于集中式消息路由器的Rust简单actor框架。

herbert支持由定义良好且长期运行的线程组成的程序架构模式,这些线程维护自己的状态并通过通道发送消息相互交互。

这种方法的缺点是跟踪所有通道,在任意线程之间传播它们,以及合理化它们的生命周期。使用集中式消息路由器,herbert解决这些挑战。路由器负责根据请求创建actor,监控和响应对其状态的更改,并将消息路由到actor之间。

这个名称灵感来自于对Taco Bell Cantina的史诗级评论

herbert-was-great

为Herbert伸张正义!


lib.rs:

actor服务和消息路由的管理。

actor是一个长期运行的线程,执行特定的功能或一系列功能,并使用协议从其他线程的请求通道中消费请求。

虽然actor模型有很多优点,但在关闭事件期间控制actor(例如)和跟踪所有通道可能具有挑战性。本模块提供支持actor模型使用的设施,解决这些挑战。

为了维护actor注册表、跟踪它们的通道并响应控制事件,启动了一个特殊的actor,称为路由器。一个Router封装了客户端与路由器及其维护的actor交互的通道。路由器的注册表将每个actor的ID映射到类似于RouterActor类型,该类型封装了actor接收输入的通道。

通过向路由器发送控制消息来创建actor。它们提供了一个ActorContext,它提供了接收输入和控制消息的通道,以及一个通道,通过它可以将其状态信息发送回路由器。

actor函数必须

  • 使用从crossbeam_channel重新导出的select!宏,从请求通道和控制通道接收消息。
  • 将它们在请求通道上接收到的Any + Send特例对象转换为正确的具体类型。
  • 通过控制通道接收到的 ActorCtl::Stop 消息时,通过及时稳定其状态,向路由器发送 ActorStatus::Stopped 状态消息,并退出。

简单示例

#[macro_use]
extern crate herbert;
use herbert::prelude::*;

fn main() {
    // Create a router. This is manditory.
    let router = Router::run("example");

    // Spawn an actor, here named "herbert".
    spawn_actor!(router, "herbert", |ctx: ActorContext| {
        loop {
            select! {
                // Normal message channel.
                recv(ctx.req) -> msg => {
                    match msg {
                        Ok(any) => {
                            // Convert trait object into concrete type.
                            if let Some(value) = any.downcast_ref::<String>() {
                                // Do some work.
                                println!("received order: {}", value);
                            } else {
                                // Bad value, here we're just ignoring it.
                            }
                        }
                        Err(e) => {
                            // Error receiving a normal message, choosing to terminate.
                            break;
                        }
                    }
                }
                // Control message channel.
                recv(ctx.ctl) -> msg => {
                    match msg {
                        Ok(ActorCtl::Stop) => {
                            // We have been requested to stop.
                            // Stabilize any state and then break the loop to exit.
                            break;
                        }
                        Err(e) => {
                            // Error receiving a control message, choosing to terminate.
                            break;
                        },
                    }
                }
            }
        }
        // Notify the router we are stopped as our last action.
        ctx.report_stopped().unwrap();
    }).unwrap();

    // Send our order to the "herbert" actor thread.
    send_actor!(router, "herbert", String::from("2 gorditas")).unwrap();

    // ...

    // Shut down the router.
    router.shutdown();
}

你需要的东西。

crossbeam_channel 中重新导出几个项目,包括 unbounded 通道类型,ReceiverSender 类型,以及 select! 宏。

依赖项

~505KB