#maelstrom #distributed #gossip #service #glomers

nebkor-maelstrom

一个易于使用且同步的创建 Maelstrom 分布式客户端的客户端

3 个版本 (1 个稳定版)

1.0.0 2024 年 6 月 10 日
0.0.2 2024 年 6 月 5 日
0.0.1 2024 年 6 月 5 日

数据库接口 中排名 #478

每月下载 34

自定义许可

20KB
356

同步且简单的 Maelstrom crate

nebkor-maelstreom 是一个简洁且简单的同步库,用于编写兼容 Maelstrom 的分布式演员。它有三个依赖项

  • serde
  • serde_json
  • serde_repr

有关简单示例,请参阅 echo 示例

use nebkor_maelstrom::{Body, Message, Node, Runner};

struct Echo;

impl Node for Echo {
    fn handle(&mut self, runner: &Runner, msg: Message) {
        let typ = &msg.body.typ;
        if typ.as_str() == "echo" {
            let body = Body::from_type("echo_ok").with_payload(msg.body.payload.clone());
            runner.reply(&msg, body);
        }
    }
}

fn main() {
    let node = Echo;

    let runner = Runner::new(node);

    runner.run(None);
}

有关稍微复杂一些的示例,请查看 broadcast 示例,它通过单个节点挑战,但完全失败了最友好的(例如,没有分区或延迟)多节点挑战,所以希望没有泄露太多。

功能

  • 无异步
  • 最少模板代码
  • 有效的 RPC 调用(允许主线程在处理消息的同时调用其他节点并接收回复)
  • 代理 Maelstrom KV 服务,使用 RPC 机制提供 readwritecas 操作,并将 Result<Option<serde_json::Value>, ErrorCode> 返回给调用者

如何使用

为它创建一个结构体并为其实现 nebkor_maelstrom::Node,这需要实现一个方法,即 handle(&mut self, &Runner, Message)。该方法传递一个 Runner,其中包含如 sendreplyrpc 等方法。

在主函数中,实例化该结构体,并将其传递给 Runner::new() 以获得一个 Runner。该 run() 方法接受一个可选的回调函数,该函数将在收到 init 消息时执行;请参见 广播 示例,其中从回调中启动一个线程,以定期向节点发送消息。

设计考虑

我希望客户端代码尽可能简单,尽量减少模板代码。使用 &mut self 作为 handle() 方法的接收者,可以在需要时轻松修改节点中的状态,而不需要 Rc<Mutex<>> 等礼节的操作。避免使用 async 可以减少一个数量级的依赖,整个工作空间(crate 和客户端)可以在几秒钟内编译完成。

它还假设某些事情是不可避免的。例如,在调用 send()recv() 时,对 MPSC 通道进行大量 unwrap(),因为这些类型的错误不是 Maelstrom 协议的一部分;这个 crate 不是一个面向真实世界的通用网络客户端 crate。同样,stdinstdout 始终假设可用且可靠;这两个通道是连接节点到 Maelstrom 路由器的物理层,Gossip Glomers 不负责这些失败。

另一个考虑因素是 crate 本身的可理解性;您应该能够轻松地从您的 IDE 或浏览器中查看其源代码。

致谢

我从 Maelbreaker 直接抄袭了 IO/网络系统的设计,这使得我能够实现一个工作的 RPC 调用。谢谢!还要感谢 Nicole,是她鼓励我发布这个项目。

依赖关系

~0.8–1.7MB
~36K SLoC