6个版本

0.0.6 2020年11月14日
0.0.5 2020年11月14日

#26 in #调度

MIT 许可证

46KB
1K SLoC

Quix

Actix的分发层。旨在遵循Actix设定的规范,并实现分发功能,类似于Erlang的dist

用法

文档

Protobuf

message M1 {

}
service Exec{
  rpc Method(M1) returns(M1);
}

代码

#[derive(quix::ProcessDispatch)]
#[dispatch(Method)]
pub struct Act {}

impl Actor for Act {

    type Context = Process<Self>;

    fn started(&mut self, ctx: &mut Self::Context) {
        let pid : Pid<Self> = ctx.pid();
        pid.do_send(M1 { v: 0 });
    }
}
impl Handler<Method> for Act { 
    type Response = Result<M1, DispatchError>;
... 
}

消息

内部和用户消息都使用Protobuf格式进行序列化。从protobuf传递给prost的Messages是独立的。

我们将protobuf服务中的RPC条目用作通信单元。每个RPC生成一个结构体,该结构体实现了Serviceactix::Message。用户需要

  1. 实现Handler<M>来消费他想要使用的指定Processactor的RPC
  2. 在包含RPC结构的actor上派生ProcessDispatch

进程

为了更好地处理分发,我们将引入进程的概念,它只是一个已标识的actor。这个actor不是通过Addr<A>结构来引用的,而是通过Pid<A>来引用的,它可以

  1. Pid::Local 包装 Addr<A> 并透明地将消息传递到该地址
  2. Pid::Remote 包含全局进程ID,并使用本地进程注册表来确定消息的发送位置

可以通过两种方式获得Pid<A>

  1. 使用Process<A>而不是Context<A> - 新的actor上下文类型,具有稳定的标识符
  2. 接收包含一个 Pid<A> 的消息 - Pid 是透明的,可以在节点之间发送。分发子系统应通过节点本地注册表内部处理节点查找。

进程注册表

是一个节点本地的单例,其中包含演员的映射。进程在启动和停止时自动从该注册表中注册和注销。注册表使用八卦协议获取整个集群的粗略图像。

消息分发

所有需要跨越网络边界的消息都必须使用 protobuf 进行序列化。

ProcessDispatch 特性负责创建一个执行消息序列化和分发的 Dispatcher。它可以由一个过程宏实现。

#[derive(quix::ProcessDispatch)]
#[dispatch(M1, M2)]
pub struct Act {}

impl Actor for Act {
    type Context = Process<Self>;
}
impl Handler<M1> for Act { ... }
impl Handler<M2> for Act { ... }
impl Handler<M3> for Act { ... }

Act 演员可以本地响应 M1M2M3,但只能响应远程提交的 M1M2

依赖项

~12-22MB
~292K SLoC