forked from makslevental/raft_demo_mpcs2022
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathraft.py
88 lines (66 loc) · 2.03 KB
/
raft.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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import dataclasses
from dataclasses import dataclass
from enum import Enum
import requests
from logg import debug_print
from timer import ResettableTimer
class Role(Enum):
Follower = "Follower"
Leader = "Leader"
Candidate = "Candidate"
@dataclass
class PersistentState:
pass
@dataclass
class LogEntry:
message: str
term: int
@dataclass
class VoteRequest:
term: int
candidate_id: int
last_log_index: int
last_log_term: int
def serialize(rpc):
return {"class": rpc.__class__.__qualname__, "dict": dataclasses.asdict(rpc)}
def deserialize(rpc_dict):
return globals()[rpc_dict["class"]](**rpc_dict["dict"])
class Node:
def __init__(self, id, peers):
self.id = id
self.current_term = 0
self.role = Role.Candidate
self.peers = peers
self.log = []
self.election_timer = ResettableTimer(self.run_election)
# self.election_timer.run()
def rpc_handler(self, sender_id, rpc_message_json):
debug_print("received rpc str", sender_id, rpc_message_json)
rpc_message = deserialize(rpc_message_json)
debug_print("received rpc", rpc_message)
return {"thank you": "come again"}
def run_election(self):
if self.role == Role.Leader:
return
debug_print("starting election")
self.broadcast_fn(
serialize(
VoteRequest(
self.current_term,
self.id,
self.get_last_log_index(),
self.get_last_log_term(),
)
)
)
def broadcast_fn(self, json_payload):
for _ip, port in self.peers:
res = requests.post(
f"http://localhost:{port}/request-vote/{self.id}", json=json_payload
)
if res.ok:
print(res.json())
def get_last_log_index(self):
return len(self.log) - 1
def get_last_log_term(self):
return self.log[self.get_last_log_index()].term if len(self.log) else -1