paxos_rust/
acceptor.rs

1//! Acceptor
2
3use message::{AcceptedData, Message, Messenger, PromiseData};
4use std::sync::Arc;
5
6/// The Acceptors act as the fault-tolerant "memory" of the protocol. Acceptors
7/// are collected into groups called Quorums. Any message sent to an Acceptor
8/// must be sent to a Quorum of Acceptors. Any message received from an Acceptor
9/// is ignored unless a copy is received from each Acceptor in a Quorum.
10pub struct Acceptor<T> {
11    /// `Acceptor`'s ID
12    pub id: u64,
13    /// The highest proposal number promised
14    pub proposal_n: u64,
15    /// The currently promised value
16    pub value: Option<Arc<T>>,
17    /// `Messenger` specifying communication with other nodes
18    pub messenger: Option<Box<Messenger<T>>>,
19}
20
21impl<T> Acceptor<T> {
22    /// Creates a new `Acceptor`.
23    pub fn new(id: u64) -> Self {
24        Self {
25            id,
26            proposal_n: 0,
27            value: None,
28            messenger: None,
29        }
30    }
31
32    /// Receives a `Prepare` message from a `Proposer`.
33    pub fn receive_prepare(&mut self, msg: &Message<T>) {
34        if let Message::Prepare(data) = msg {
35            if data.id > self.proposal_n {
36                self.proposal_n = data.id;
37                let promise = Message::Promise(PromiseData {
38                    id: self.proposal_n,
39                    value: self.value.clone(),
40                    from: self.id,
41                });
42                if let Some(ref mut messenger) = self.messenger {
43                    messenger.send_promise(promise);
44                }
45            }
46        }
47    }
48
49    /// Receives an `Accept` message from a `Proposer`.
50    pub fn receive_accept(&mut self, msg: &Message<T>) {
51        if let Message::Accept(data) = msg {
52            if data.id >= self.proposal_n {
53                self.value = Some(data.value.clone());
54                self.proposal_n = data.id;
55                let accepted = Message::Accepted(AcceptedData {
56                    id: self.proposal_n,
57                    value: data.value.clone(),
58                    from: self.id,
59                });
60                if let Some(ref mut messenger) = self.messenger {
61                    messenger.send_accepted(accepted);
62                }
63            }
64        }
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71    use message::{AcceptData, ProposalData};
72
73    #[test]
74    fn acceptor_new() {
75        let a: Acceptor<u64> = Acceptor::new(1);
76
77        assert_eq!(a.id, 1);
78        assert_eq!(a.proposal_n, 0);
79        assert_eq!(a.value, None);
80        assert!(a.messenger.is_none());
81    }
82
83    #[test]
84    fn acceptor_receive_prepare() {
85        let mut a: Acceptor<u64> = Acceptor::new(1);
86
87        let msg = Message::Prepare(ProposalData { id: 8 });
88
89        a.receive_prepare(&msg);
90
91        assert_eq!(a.proposal_n, 8);
92
93        // ignore proposals less than N
94        let msg = Message::Prepare(ProposalData { id: 6 });
95
96        a.receive_prepare(&msg);
97
98        assert_eq!(a.proposal_n, 8);
99    }
100
101    #[test]
102    fn acceptor_receive_accept() {
103        let mut a: Acceptor<u64> = Acceptor::new(1);
104
105        let msg = Message::Accept(AcceptData {
106            id: 3,
107            value: Arc::new(60),
108        });
109
110        a.receive_accept(&msg);
111
112        assert_eq!(a.value, Some(Arc::new(60)));
113        assert_eq!(a.proposal_n, 3);
114
115        // ignore Accept messages less than N
116
117        let msg = Message::Accept(AcceptData {
118            id: 2,
119            value: Arc::new(60),
120        });
121
122        a.receive_accept(&msg);
123
124        assert_eq!(a.value, Some(Arc::new(60)));
125        assert_eq!(a.proposal_n, 3);
126    }
127}