27个版本

0.10.3 2024年5月24日
0.9.8 2024年5月2日
0.9.7 2024年3月16日
0.9.3 2023年10月13日
0.7.5 2023年3月24日

834异步

Download history 184/week @ 2024-04-27 17/week @ 2024-05-04 6/week @ 2024-05-11 613/week @ 2024-05-18 138/week @ 2024-05-25 36/week @ 2024-06-01 13/week @ 2024-06-08 79/week @ 2024-06-15 59/week @ 2024-06-22 45/week @ 2024-06-29 95/week @ 2024-07-06 114/week @ 2024-07-13 38/week @ 2024-07-20 56/week @ 2024-07-27 18/week @ 2024-08-03 22/week @ 2024-08-10

139 每月下载量

MIT 许可证

715KB
15K SLoC

ractor_cluster

ractor 的配套库,用于支持远程演员

github crates.io docs.rs CI/main codecov ractor_cluster Downloads

此库包含对 ractor 的扩展,是一个纯Rust演员框架。灵感来源于 Erlang的 gen_server

网站 Ractor有一个配套网站,提供更详细的入门指南和一些最佳实践,并定期更新。Api文档仍可在 docs.rs 上找到,但这将是 ractor 的补充网站。试试看! https://slawlor.github.io/ractor/

关于

ractor_cluster 扩展了 ractor 演员以支持通过网络链接进行传输和在演员网络集群上同步演员。

安装

通过在您的 Cargo.toml 依赖项中添加以下内容来安装 ractor_cluster

[dependencies]
ractor = { version = "0.9", features = ["cluster"] }
ractor_cluster = "0.9"

Ractor在分布式集群中

Ractor演员可以在类似 Erlang的 EPMD 的网络分布式演员池中构建,它管理节点间的连接和节点命名。在我们的实现中,我们使用了 ractor_cluster 以促进分布式 ractor 演员。

ractor_cluster 中有一个主要类型,即代表一个 node 进程的主机 NodeServer。它还包含一些宏和过程宏,以在构建分布式演员时提高开发效率。 NodeServer 负责以下任务:

  1. 管理所有传入和传出的代表连接到此主机的远程节点 NodeSession 演员。
  2. 管理 TcpListener,它承载服务器套接字以接收传入的会话请求(带或不带加密)。

然而,节点互连的大部分逻辑都包含在NodeSession中,该模块负责管理

  1. 底层的TCP连接,负责对流的读写。
  2. 本节点与对等连接之间的身份验证
  3. 管理在远程系统上生成的actor的生命周期。
  4. 在节点之间传输所有actor间消息。
  5. 管理PG组同步

等等。

NodeSession通过生成RemoteActor在远程系统上使本地actor可用,这些actor本质上是无类型的actor,仅处理序列化消息,将消息反序列化留给源系统。它还跟踪挂起的RPC请求,以便在回复时匹配请求和响应。在ractor中有特殊的扩展点,这些扩展点是为了特别支持不在标准

Actor::spawn(Some("name".to_string()), MyActor).await

模式外使用的RemoteActor而添加的。

快速入门

设置actor网络集群的基础知识包含在NodeServer结构体中。该结构体处理服务器端口的底层网络所有权以及集群互连的所有生命周期。通过生成这个单一的结构体,您可以接受主机之间的传入连接!

网络中的节点按照Erlang规范中的“魔法cookie”相互认证,规范请参考Erlang的分布协议。如果您想连接到另一个主机,您需要

  1. 初始化您自己的NodeServer
  2. 执行对您想要连接的远程NodeServer的“客户端连接”操作,如下所示
let host = "1.2.3.4";
let port = "4697";
ractor_cluster::client_connect(
    &actor,
    format!("{host}:{port}"),
)

类似地,还有一个client_connect_enc可以连接到使用加密通信的NodeServer。这就是全部!如果您的节点共享正确的魔法cookie值,它们应该相互认证,您将在本地系统上看到远程actor生成,您可以通过各种基于pgpid的注册表与之通信。

设计支持远程的actor

注意并非所有actor都同等重要。actor需要支持通过网络链路发送其消息类型。这是通过覆盖所有消息都需要支持的ractor::Message特质的特定方法来实现的。由于Rust中缺乏特化支持,如果您选择使用ractor_cluster,您需要为您的crate中的所有消息类型派生ractor::Message特质。但是,为了支持这一点,我们提供了一些过程宏来简化这个过程

为仅进程内的actor派生基本Message特质

许多actor将是本地的,并且不需要通过网络链路发送消息。这是最基本的情况,在这种情况下,默认的ractor::Message特质实现就足够了。您可以使用以下方法快速派生它

use ractor_cluster::RactorMessage;
use ractor::RpcReplyPort;

#[derive(RactorMessage)]
enum MyBasicMessageType {
    Cast1(String, u64),
    Call1(u8, i64, RpcReplyPort<Vec<String>>),
}

这将为您实现默认的ractor::Message特质,而无需您手动编写。

为远程actor派生网络序列化消息特质

如果您想使您的actor支持远程,那么您应该使用不同的派生语句,即

use ractor_cluster::RactorClusterMessage;
use ractor::RpcReplyPort;

#[derive(RactorClusterMessage)]
enum MyBasicMessageType {
    Cast1(String, u64),
    #[rpc]
    Call1(u8, i64, RpcReplyPort<Vec<String>>),
}

这为实现添加了大量的底层模板代码(你自己看看吧,用 cargo expand!)。简而言之,每个枚举变体需要序列化为一个参数字节数组、一个变体名称,如果是RPC,还需要提供一个接收字节数组并反序列化回复的端口。参数或回复类型内部的所有类型都需要实现 ractor_cluster::BytesConvertable 特性,它仅仅表示这个值可以被写入字节数组并从字节数组中解码。如果你使用 prost 为你的消息类型定义(protobuf),我们有一个宏可以自动为你实现这个特性。

ractor_cluster::derive_serialization_for_prost_type! {MyProtobufType}

除此之外,只需像平时一样编写你的actor。actor本身将存在于你定义的位置,并将能够接收来自其他集群通过网络链接发送的消息!

贡献者

ractor 的原始作者是Sean Lawlor (@slawlor)。想了解更多关于向 ractor 贡献的信息,请参阅 CONTRIBUTING.md

许可证

本项目使用 MIT 许可证。

依赖

~13–27MB
~500K SLoC