#node #distributed #building-block #async-io #constructing #construct #non-blocking

bin+lib EasyDist

一个用于构建简单分布式项目的非阻塞 IO 和易于使用的 Rust 包。该包包含几个构建块,可用于构建分布式系统程序。

1 个不稳定版本

新版本 0.2.0 2024年8月19日

#254异步

MIT 许可证

170KB
3.5K SLoC

EasyDist

一个用于构建简单分布式系统的非阻塞 IO 和易于使用的 Rust 包。该包包含几个构建块,可用于构建分布式系统程序。在 node 模块中定义的方法可以建立两个节点之间的连接。一旦建立连接,节点会将彼此添加到邻居列表中,并持续向彼此发送 heartbeat 消息以检查活动。您可以通过 senduserdefinedmsg 方法轻松定义自己的逻辑。您只需要注册一个具有特定名称的处理方法,并可以使用此特定名称定义处理逻辑。当然,您可以选择 sendecdsaencmsgsendrsaencmsg 来实现相同的功能,并使用更安全的消息通信。

示例

这是一个初始化节点实例的示例代码。此示例接受两个参数,第一个是您选择的节点 ID,第二个是您选择的本地网络端口。例如,0 127.0.0.1:8080 表示您选择将节点 ID 设置为 0,并将节点绑定到本机的 8080 端口。这也是此代码的默认输入(即不输入任何参数)。

#[tokio::main()]
async fn main() -> std::io::Result<()> {
    // The first argument is the id of node.
    // The second is the addr of node.
    let args: Vec<String> = env::args().collect();

    // Initiate the env_logger.
   env_logger::init();

   // If there is no argument, use the configuration in config.rs
   let node = if args.len() > 2 {
       Arc::new(Node::new(
           args[1]
               .parse::<u64>()
               .expect("The first argument must can be converted to u64."),
           &args[2],
       ))
   } else {
       Arc::new(Node::default())
   };

   // Run the node.
   node.run().await;

   tokio::signal::ctrl_c()
       .await
       .expect("Failed to listen for ctrl_c");

   Ok(())
}

这是使用处理器的示例。

#[derive(Serialize, Deserialize, Debug)]
struct Point {
    id: u64,
    x: i32,
    y: i32,
}

pub struct CustomHandler;

#[async_trait]
impl UserMessageHandler for CustomHandler {
    async fn handle(&self, message: UserDefined, connection: Arc<Node>) -> EasyDist::Result<()> {
        let point: Point = serde_json::from_slice(&message.get_data()).unwrap();
        println!("ping received: {:?}.", point);
        let data = vec![];
        connection
            .send_ecdsa_signed_msg(point.id, "OK", &data)
            .await?;
        Ok(())
    }
}

#[tokio::main()]
async fn main() -> std::io::Result<()> {
   // The first argument is the id of node.
   // The second is the addr of node.
   let args: Vec<String> = env::args().collect();

   // Initiate the env_logger.
   env_logger::init();

   // If there is no argument, use the configuration in config.rs
   let node = if args.len() > 2 {
       Arc::new(Node::new(
           args[1]
               .parse::<u64>()
               .expect("The first argument must can be converted to u64."),
           &args[2],
       ))
   } else {
       Arc::new(Node::default())
   };

   let handle = Arc::new(CustomHandler {});
   let _ = node.clone().register_user_handler("ping", handle).await;

   // Run the node.
   node.run().await;

   tokio::signal::ctrl_c()
       .await
       .expect("Failed to listen for ctrl_c");
   println!("Shutting down...");

   Ok(())
}

依赖关系

~13–25MB
~385K SLoC