Ejemplo n.º 1
0
    def request_vote_from_peers(self):
        if self.state != ConsensusState.CANDIDATE:
            return
        votes_received = 1
        peers = {server: address for server, address in cluster_info_by_name.items() if self.raft_server.name != server}

        # We can use a with statement to ensure threads are cleaned up promptly
        with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
            future_to_server = {executor.submit(self.do_rpc_request, server, address): server for
                                server, address in peers.items()}
            for future in concurrent.futures.as_completed(future_to_server):
                server = future_to_server[future]
                try:
                    data = future.result()
                except Exception as exc:
                    print(f"{self.raft_server.name} : [ {server} ] generated an exception {exc}")
                else:
                    print(f"{self.raft_server.name} : Result from {server} of the Request Vote response {data}")
                    if self.state != ConsensusState.CANDIDATE:
                        print(
                            f"{self.raft_server.name} : while waiting for the reply state changed {state_to_name[self.state]}")
                        return

                    if data.VoteGranted:
                        votes_received = votes_received + 1

        print(f"{self.raft_server.name} : For a current term {self.current_term} the votes received {votes_received}")
        nodes_that_can_fail = (len(cluster_info_by_name) - 1) / 2
        if votes_received > nodes_that_can_fail:
            print(f"{self.raft_server.name} : Got majority of votes .. Lets roll and become leader")
            self.become_leader()

        # Run timer in case of split votes
        self.run_election_timer()
Ejemplo n.º 2
0
    def send_heart_beat(self):
        peers = {server: address for server, address in cluster_info_by_name.items() if self.raft_server.name != server}

        # We can use a with statement to ensure threads are cleaned up promptly
        with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
            future_to_server = {executor.submit(self.do_heartbeat_rpc_request, server, address): server for
                                server, address in peers.items()}
            for future in concurrent.futures.as_completed(future_to_server):
                server = future_to_server[future]
                try:
                    data = future.result()
                except Exception as exc:
                    print(f"{self.raft_server.name} : [ {server} ] generated an exception {exc}")
                else:
                    print(f"{self.raft_server.name} : Result from {server} of the Heart Beat response {data}")
                    if data.Term > self.current_term:
                        print(f"{self.raft_server.name} : Term out of date in Heartbeat reply")
                        self.become_follower(data.Term)
                        return
Ejemplo n.º 3
0
    def connect_rpc_clients(self):
        while True:
            for server, address in cluster_info_by_name.items():
                if server != self.name:
                    if self.consensusModule.peers.get(server, None) is None:
                        print(
                            f"{self.name} : trying to connect to {server} at {address}"
                        )
                        try:
                            remote = RPCProxy(cluster_info_by_name[server],
                                              authkey=b"peekaboo",
                                              timeout=2)
                        except Exception as e:
                            print(
                                f"{self.name} : [ {server} ] generated an exception: {e}"
                            )
                        else:
                            self.consensusModule.peers[server] = remote

            time.sleep(1)