Пример #1
0
 def debug_statistics(self):
     return {
         "node":
         lib.raft_get_nodeid(self.raft),
         "state":
         state2str(lib.raft_get_state(self.raft)),
         "current_idx":
         lib.raft_get_current_idx(self.raft),
         "last_log_term":
         lib.raft_get_last_log_term(self.raft),
         "current_term":
         lib.raft_get_current_term(self.raft),
         "commit_idx":
         lib.raft_get_commit_idx(self.raft),
         "last_applied_idx":
         lib.raft_get_last_applied_idx(self.raft),
         "log_count":
         lib.raft_get_log_count(self.raft),
         "peers":
         lib.raft_get_num_nodes(self.raft),
         "voting_peers":
         lib.raft_get_num_voting_nodes(self.raft),
         "connection_status":
         connectstatus2str(self.connection_status),
         "voting_change_in_progress":
         lib.raft_voting_change_is_in_progress(self.raft),
         "removed":
         getattr(self, 'removed', False),
     }
Пример #2
0
 def _check_committed_entry_popping(self, ety_idx):
     """
     Check we aren't popping a committed entry
     """
     try:
         assert lib.raft_get_commit_idx(self.raft) < ety_idx
     except Exception as e:
         self.abort_exception = e
         return lib.RAFT_ERR_SHUTDOWN
     return 0
Пример #3
0
    def _check_log_matching(self, our_log, idx):
        """
        Quality:

        Log Matching: if two logs contain an entry with the same index and
        term, then the logs are identical in all entries up through the given
        index. §5.3

        State Machine Safety: if a server has applied a log entry at a given
        index to its state machine, no other server will ever apply a
        different log entry for the same index. §5.4.3
        """
        for server in self.network.active_servers:
            if server is self:
                continue
            their_commit_idx = lib.raft_get_commit_idx(server.raft)
            if lib.raft_get_commit_idx(
                    self.raft) <= their_commit_idx and idx <= their_commit_idx:
                their_log = lib.raft_get_entry_from_idx(server.raft, idx)

                if their_log == ffi.NULL:
                    assert idx < lib.raft_get_snapshot_last_idx(self.raft)

                if their_log.type in [lib.RAFT_LOGTYPE_NORMAL]:
                    try:
                        assert their_log.term == our_log.term
                        assert their_log.id == our_log.id
                    except Exception as e:
                        ety1 = lib.raft_get_entry_from_idx(self.raft, idx)
                        ety2 = lib.raft_get_entry_from_idx(server.raft, idx)
                        logger.error('ids', ety1.id, ety2.id)
                        logger.error(
                            '{0}vs{1} idx:{2} terms:{3} {4} ids:{5} {6}'.
                            format(self, server, idx, our_log.term,
                                   their_log.term, our_log.id, their_log.id))
                        self.abort_exception = e

                        logger.error(self.debug_log())
                        logger.error(server.debug_log())
                        return lib.RAFT_ERR_SHUTDOWN
                lib.raft_entry_release(their_log)