1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use super::*;

#[derive(Default, Debug, Clone)]
pub struct Acceptor {
    highest_seen: Ballot,
    last_accepted_ballot: Ballot,
    last_accepted_value: Option<Value>,
}

impl Reactor for Acceptor {
    type Peer = String;
    type Message = Rpc;

    fn receive(
        &mut self,
        _at: SystemTime,
        from: Self::Peer,
        msg: Self::Message,
    ) -> Vec<(Self::Peer, Self::Message)> {
        match msg {
            ProposeReq(ballot) => {
                if ballot > self.highest_seen {
                    self.highest_seen = ballot.clone();
                    vec![
                        (
                            from,
                            ProposeRes {
                                req_ballot: ballot,
                                last_accepted_ballot: self.last_accepted_ballot
                                    .clone(),
                                last_accepted_value: self.last_accepted_value
                                    .clone(),
                                res: Ok(()),
                            }
                        ),
                    ]
                } else {
                    vec![
                        (
                            from,
                            ProposeRes {
                                req_ballot: ballot,
                                last_accepted_ballot: self.last_accepted_ballot
                                    .clone(),
                                last_accepted_value: self.last_accepted_value
                                    .clone(),
                                res: Err(Error::ProposalRejected {
                                    last: self.highest_seen.clone(),
                                }),
                            }
                        ),
                    ]
                }
            }
            AcceptReq(ballot, to) => {
                if ballot >= self.highest_seen {
                    self.highest_seen = ballot.clone();
                    self.last_accepted_ballot = ballot.clone();
                    self.last_accepted_value = to;
                    vec![(from, AcceptRes(ballot, Ok(())))]
                } else {
                    vec![
                        (
                            from,
                            AcceptRes(
                                ballot,
                                Err(Error::AcceptRejected {
                                    last: self.highest_seen.clone(),
                                }),
                            )
                        ),
                    ]
                }
            }
            _ => panic!("Acceptor got non-propose/accept"),
        }
    }
}