alopex_chirps_wire/
frame.rs

1use crate::file_transfer::FileTransferFrame;
2use crate::node_id::NodeId;
3use serde::{Deserialize, Serialize};
4use std::net::SocketAddr;
5
6/// A frame is the unit of communication between nodes.
7#[allow(clippy::large_enum_variant)]
8#[derive(Serialize, Deserialize, Debug, Clone)]
9pub enum Frame {
10    Ping {
11        seq: u64,
12        from: NodeId,
13    },
14    Ack {
15        seq: u64,
16        from: NodeId,
17    },
18    PingReq {
19        seq: u64,
20        from: NodeId,
21        target: NodeId,
22    },
23    Gossip(GossipMessage),
24    User(UserMessage),
25    /// Raft RPC用の汎用フレーム。payloadは上位層でbincodeシリアライズされたRPCを格納する。
26    Raft(RaftFrame),
27    /// スナップショット転送専用フレーム。
28    RaftSnapshot(RaftFrame),
29    /// ファイル転送制御フレーム。
30    FileTransfer(FileTransferFrame),
31}
32
33/// A gossip message containing membership updates.
34#[derive(Serialize, Deserialize, Debug, Clone)]
35pub struct GossipMessage {
36    pub updates: Vec<MembershipUpdate>,
37}
38
39/// A user-defined message.
40#[derive(Serialize, Deserialize, Debug, Clone)]
41pub struct UserMessage {
42    pub payload: Vec<u8>,
43}
44
45/// Raft関連のペイロードを運ぶフレーム。
46#[derive(Serialize, Deserialize, Debug, Clone)]
47pub struct RaftFrame {
48    /// Raftグループを識別するID。
49    pub group_id: u64,
50    /// シリアライズ済みのRPC/レスポンス。
51    pub payload: Vec<u8>,
52}
53
54/// An update to the membership list.
55#[derive(Serialize, Deserialize, Debug, Clone)]
56pub struct MembershipUpdate {
57    pub node_id: NodeId,
58    pub incarnation: u64,
59    pub addr: SocketAddr,
60    pub status: MemberStatus,
61}
62
63/// The status of a member in the cluster.
64#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
65pub enum MemberStatus {
66    Alive,
67    Suspect,
68    Dead,
69}
70
71#[cfg(test)]
72mod tests {
73    use super::*;
74
75    #[test]
76    fn test_create_ping_frame() {
77        let node_id = NodeId::new();
78        let frame = Frame::Ping {
79            seq: 123,
80            from: node_id,
81        };
82        match frame {
83            Frame::Ping { seq, from } => {
84                assert_eq!(seq, 123);
85                assert_eq!(from, node_id);
86            }
87            _ => panic!("Expected a Ping frame"),
88        }
89    }
90
91    #[test]
92    fn test_create_ping_req_frame() {
93        let node_id1 = NodeId::new();
94        let node_id2 = NodeId::new();
95        let frame = Frame::PingReq {
96            seq: 456,
97            from: node_id1,
98            target: node_id2,
99        };
100        match frame {
101            Frame::PingReq { seq, from, target } => {
102                assert_eq!(seq, 456);
103                assert_eq!(from, node_id1);
104                assert_eq!(target, node_id2);
105            }
106            _ => panic!("Expected a PingReq frame"),
107        }
108    }
109}