sdcons/
types.rs

1//! The crate `types` defines a set types used by sdcons.
2
3// Copyright 2021 The sdcons Authors.
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9//     http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17use std::collections::{HashMap, HashSet};
18
19use serde::{Deserialize, Serialize};
20
21use crate::constant::*;
22
23#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
24pub struct HardState {
25    pub voted_for: u64,
26    pub current_term: u64,
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
30pub struct MemberState {
31    pub stage: ConfigStage,
32
33    /// applied means this member has a active channel, that indicates that this
34    /// member already applied.
35    pub applied: bool,
36}
37
38impl Default for MemberState {
39    fn default() -> MemberState {
40        MemberState {
41            stage: ConfigStage::New,
42            applied: true,
43        }
44    }
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct EntryMeta {
49    pub id: u64,
50    pub term: u64,
51}
52
53impl Default for EntryMeta {
54    fn default() -> EntryMeta {
55        EntryMeta {
56            id: INVALID_ID,
57            term: INITIAL_TERM,
58        }
59    }
60}
61
62impl Default for HardState {
63    fn default() -> HardState {
64        HardState {
65            voted_for: INVALID_NODE_ID,
66            current_term: INITIAL_TERM,
67        }
68    }
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct Task {
73    pub message: Vec<u8>,
74    pub context: Option<Vec<u8>>,
75}
76
77#[derive(Serialize, Deserialize, Clone, Debug)]
78pub struct SnapshotDesc {
79    pub located_id: u64,
80    pub url: String,
81    pub channel_metas: HashMap<u64, EntryMeta>,
82    pub members: HashMap<u64, MemberState>,
83}
84
85impl SnapshotDesc {
86    pub fn applied_ids(&self) -> HashMap<u64, u64> {
87        self.channel_metas
88            .iter()
89            .map(|(id, v)| (*id, v.id))
90            .collect()
91    }
92}
93
94#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone, Copy)]
95pub enum ConfigStage {
96    Old,
97    Both,
98    New,
99}
100
101#[derive(Serialize, Deserialize, Clone, Debug)]
102pub struct ChangeConfig {
103    pub index_id: u64,
104    pub entry_id: u64,
105    pub term: u64,
106    pub stage: ConfigStage,
107    pub members: HashSet<u64>,
108}
109
110#[derive(Serialize, Deserialize, Clone)]
111pub struct Entry {
112    pub request_id: u64,
113    pub channel_id: u64,
114    pub index_id: u64,
115    pub entry_id: u64,
116    pub channel_term: u64,
117    pub message: Vec<u8>,
118    pub context: Option<Vec<u8>>,
119    pub configs: Option<ChangeConfig>,
120}
121
122impl From<&Entry> for EntryMeta {
123    fn from(entry: &Entry) -> Self {
124        EntryMeta {
125            id: entry.entry_id,
126            term: entry.channel_term,
127        }
128    }
129}
130
131#[derive(Debug, Serialize, Deserialize, Clone)]
132pub struct LogIndex {
133    pub channel_id: u64,
134    pub entry_id: u64,
135    pub index_id: u64,
136    pub term: u64,
137    pub context: Option<Vec<u8>>,
138}
139
140impl std::fmt::Debug for Entry {
141    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
142        f.debug_struct("Entry")
143            .field("request_id", &self.request_id)
144            .field("channel_id", &self.channel_id)
145            .field("entry_id", &self.entry_id)
146            .field("channel_term", &self.channel_term)
147            .finish()
148    }
149}
150
151#[derive(Debug, Clone, Serialize, Deserialize)]
152pub struct VoteMsg {
153    pub last_index_id: u64,
154    pub last_index_term: u64,
155}
156
157#[derive(Debug, Clone, Serialize, Deserialize)]
158pub struct VoteReplyMsg {
159    pub reject: bool,
160}
161
162#[derive(Debug, Clone, Serialize, Deserialize)]
163pub struct PrepareMsg {
164    pub learn: bool,
165    pub committed_entry_id: u64,
166}
167
168#[derive(Clone, Serialize, Deserialize)]
169pub struct PrepareReplyMsg {
170    pub entry_metas: Vec<EntryMeta>,
171    pub learn: bool,
172    pub reject: bool,
173}
174
175impl std::fmt::Debug for PrepareReplyMsg {
176    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
177        let num_entries = self.entry_metas.len();
178        f.debug_struct("PrepareReplyMsg")
179            .field("reject", &self.reject)
180            .field("learn", &self.learn)
181            .field("num_entries", &num_entries)
182            .finish()
183    }
184}
185
186#[derive(Clone, Serialize, Deserialize)]
187pub struct AppendMsg {
188    pub committed_entry_id: u64,
189    pub prev_entry_id: u64,
190    pub prev_entry_term: u64,
191    pub entries: Vec<Entry>,
192}
193
194impl std::fmt::Debug for AppendMsg {
195    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
196        let num_entries = self.entries.len();
197        f.debug_struct("AppendMsg")
198            .field("committed_id", &self.committed_entry_id)
199            .field("prev_id", &self.prev_entry_id)
200            .field("prev_term", &self.prev_entry_term)
201            .field("num_entries", &num_entries)
202            .finish()
203    }
204}
205
206#[derive(Debug, Clone, Serialize, Deserialize)]
207pub struct AppendReplyMsg {
208    pub entry_id: u64,
209    pub hint_id: u64,
210    pub reject: bool,
211}
212
213#[derive(Clone, Serialize, Deserialize)]
214pub struct IndexMsg {
215    pub committed_index_id: u64,
216    pub prev_index_id: u64,
217    pub prev_index_term: u64,
218    pub indexes: Vec<LogIndex>,
219}
220
221impl std::fmt::Debug for IndexMsg {
222    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
223        let num_indexes = self.indexes.len();
224        f.debug_struct("IndexMsg")
225            .field("committed_id", &self.committed_index_id)
226            .field("prev_id", &self.prev_index_id)
227            .field("prev_term", &self.prev_index_term)
228            .field("num_indexes", &num_indexes)
229            .finish()
230    }
231}
232
233#[derive(Debug, Clone, Serialize, Deserialize)]
234pub struct IndexReplyMsg {
235    pub index_id: u64,
236    pub hint_id: u64,
237    pub reject: bool,
238}
239
240#[derive(Debug, Clone, Serialize, Deserialize)]
241pub struct CommitMsg {
242    pub index_id: u64,
243}
244
245#[derive(Debug, Clone, Serialize, Deserialize)]
246pub struct DeclareMsg {
247    pub committed_id: u64,
248}
249
250#[derive(Debug, Clone, Serialize, Deserialize)]
251pub struct DeclareReplyMsg {
252    pub receiving_snapshot: bool,
253}
254
255#[derive(Debug, Clone, Serialize, Deserialize)]
256pub struct SnapshotReplyMsg {
257    pub received: bool,
258    pub hints: HashMap<u64, u64>,
259}
260
261#[derive(Debug, Clone, Serialize, Deserialize)]
262pub struct ReadMsg {
263    pub request_id: u64,
264}
265
266#[derive(Debug, Clone, Serialize, Deserialize)]
267pub struct ReadReplyMsg {
268    pub request_id: u64,
269    pub recommend_id: u64,
270}
271
272#[derive(Debug, Clone, Serialize, Deserialize)]
273pub enum MsgDetail {
274    None,
275    Vote(VoteMsg),
276    VoteReply(VoteReplyMsg),
277    Prepare(PrepareMsg),
278    PrepareReply(PrepareReplyMsg),
279    Append(AppendMsg),
280    AppendReply(AppendReplyMsg),
281    Index(IndexMsg),
282    IndexReply(IndexReplyMsg),
283    Commit(CommitMsg),
284    Declare(DeclareMsg),
285    DeclareReply(DeclareReplyMsg),
286    Snapshot(SnapshotDesc),
287    SnapshotReply(SnapshotReplyMsg),
288    Read(ReadMsg),
289    ReadReply(ReadReplyMsg),
290    TimeoutNow,
291}
292
293impl std::fmt::Display for MsgDetail {
294    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
295        let msg = match &self {
296            MsgDetail::Vote(_) => "Vote",
297            MsgDetail::VoteReply(_) => "VoteReply",
298            MsgDetail::Prepare(_) => "Prepare",
299            MsgDetail::PrepareReply(_) => "PrepareReply",
300            MsgDetail::Append(_) => "Append",
301            MsgDetail::AppendReply(_) => "AppendReply",
302            MsgDetail::Index(_) => "Index",
303            MsgDetail::IndexReply(_) => "IndexReply",
304            MsgDetail::Commit(_) => "Commit",
305            MsgDetail::Declare(_) => "Declare",
306            MsgDetail::DeclareReply(_) => "DeclareReply",
307            MsgDetail::Snapshot(_) => "Snapshot",
308            MsgDetail::SnapshotReply(_) => "SnapshotReply",
309            MsgDetail::Read(_) => "Read",
310            MsgDetail::ReadReply(_) => "ReadReply",
311            _ => "none",
312        };
313        write!(f, "{}", msg)
314    }
315}
316
317#[derive(Debug, Clone, Serialize, Deserialize)]
318pub struct Message {
319    pub from: u64,
320
321    /// Who this message send to.
322    pub to: u64,
323
324    /// The current index channel term of the message sender.
325    pub index_term: u64,
326
327    /// The id of channel of which this message details
328    pub channel_id: u64,
329    pub channel_term: u64,
330    pub detail: MsgDetail,
331}