""" This module holds the messages for raft to use. Message -- Base message class AppendEntries -- Message representing raft append entries. RequestVote -- Message representing raft request vote. RequestVoteReponse -- Message for responding to a request vote. Response -- Response to an append entries message. """ import umsgpack from enum import Enum class Messages(Enum): AppendEntries = 1 RequestVote = 2 RequestVoteResponse = 3 AppendEntriesResponse = 4 class Message: """The base class of all messages used in raft""" _type = None def __init__(self, sender, data = {}, term = 0): self._sender = sender self._data = data self._term = term @property def sender(self): return self._sender @property def type(self): return self._type def serialise(self): """Serialises a Message object into a message pack byte array""" raise NotImplementedError @staticmethod def deserialise(message): """Deserialises from a byte array into a Message object message -- Message to deserialise. Returns -- Deserialised message object, None if incorrect input message. """ m = None try: m = umsgpack.unpackb(m) except: print("Could not decode message") return m m = Message('tbd') raise NotImplementedError def __eq__(self, other): if not isinstance(other, Message): return False if other.type != self.type: return False if other._data != self._data: return False if other._sender != self._sender: return False return True class AppendEntries(Message): _type = "AppendEntries" def __init__(self, term, leaderId, prevLogIndex, prevLogTerm, leaderCommit, entries = None): self._data["term"] = term self._data["leaderId"] = leaderId self._data["prevLogIndex"] = prevLogIndex self._data["prevLogTerm"] = prevLogTerm self._data["entries"] = entries self._data["leaderCommit"] = leaderCommit # Leader's commit index. class RequestVote(Message): _type = "RequestVote" def __init__(self, term, candidate_id, last_log_index, last_log_term): self._data["candidateId"] = candidate_id self._data["lastLogIndex"] = last_log_index self._data["lastLogTerm"] = last_log_term @property def candidate_id(self): return self._data["candidateId"] @property def last_log_index(self): return self._data["lastLogIndex"] @property def last_log_term(self): return self._data["lastLogTerm"] class RequestVoteResponse(Message): _type = "RequestVoteResponse" def __init__(self, term, vote_granted): self._data["voteGranted"] = vote_granted @property def vote_granted(self): return self._data["voteGranted"] class Response(Message): _type = "Response" def __init__(self, term, success): self._data["success"] = success @property def success(self): return self._data["success"]