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), }
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
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)