-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathproposer.py
70 lines (54 loc) · 3.04 KB
/
proposer.py
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
from message_type import *;
class Proposer ():
leader = False
proposed_value = None # <client_id, client_sequence, message>
proposal_id = None # <highest_proposal_id_no, id>
highest_accepted_id = None
promises_received = None #set
nacks_received = None #set
current_prepare_msg = None #<id, <highest_proposal_id_no, id> >
current_accept_msg = None #<id, <highest_proposal_id_no, id>, proposed_value >
def __init__(self, id, quorum_size, is_leader = False):
self.id = id
self.leader = is_leader
self.quorum_size = quorum_size
self.proposal_id = (0, self.id)
self.highest_proposal_id = (0, self.id)
def prepare(self):
self.leader = False
self.promises_received = set()
self.nacks_received = set()
self.proposal_id = (self.highest_proposal_id[0] + 1, self.id)
self.highest_proposal_id = self.proposal_id
self.current_prepare_msg = (self.id, self.proposal_id)
return self.current_prepare_msg
def propose_value(self, client_message, slot):
if self.proposed_value is None:
self.proposed_value = (client_message.client_id, client_message.client_sequence, client_message.message)
if self.leader:
self.current_accept_msg = AcceptMessage(self.id, self.proposal_id, self.proposed_value, slot)
return self.current_accept_msg
def observe_proposal(self, proposal_id):
if proposal_id > self.highest_proposal_id:
self.highest_proposal_id = proposal_id
def receive_nack(self, message):
self.observe_proposal( message.promised_id )
if message.proposal_id == self.proposal_id and self.nacks_received is not None:
self.nacks_received.add( message.acceptor_id )
if len(self.nacks_received) == self.quorum_size:
return self.prepare() # Lost leadership or failed to acquire it
def receive_promise(self, message):
self.observe_proposal( message.proposal_id )
if message.proposal_id == self.proposal_id and message.acceptor_id not in self.promises_received:
#print("going to add to the promises list")
self.promises_received.add( message.acceptor_id )
if message.last_accepted_id is not None and (self.highest_accepted_id is None or message.last_accepted_id > self.highest_accepted_id):
self.highest_accepted_id = message.last_accepted_id
if message.last_accepted_value is not None:
self.proposed_value = message.last_accepted_value
#print(len(self.promises_received), self.quorum_size)
if len(self.promises_received) == self.quorum_size:
self.leader = True
if self.proposed_value is not None:
self.current_accept_msg = AcceptMessage(self.id, self.proposal_id, self.proposed_value, message.slot)
return self.current_accept_msg