def periodic(self): if self.random.randint(1, 100) < self.member_rate: self.toggle_membership() if self.random.randint(1, 100) < self.partition_rate: self.add_partition() if self.partitions and self.random.randint(1, 100) < self.partition_rate: self.remove_partition() if self.random.randint(1, 100) < self.client_rate: self.push_set_entry(self.random.randint(1, 10), self.random.randint(1, 10)) for server in self.active_servers: if self.no_random_period: server.periodic(100) else: server.periodic(self.random.randint(1, 100)) # Deadlock detection if self.latest_applied_log_idx != 0 and self.latest_applied_log_iteration + 5000 < self.iteration: logging.error("deadlock detected iteration:{0} appliedidx:{1}\n".format( self.latest_applied_log_iteration, self.latest_applied_log_idx, )) sys.exit(1) # Count leadership changes leader_node = lib.raft_get_current_leader_node(self.active_servers[0].raft) if leader_node: leader = ffi.from_handle(lib.raft_node_get_udata(leader_node)) if self.leader is not leader: self.leadership_changes += 1 self.leader = leader
def raft_send_appendentries(raft, udata, node, msg): server = ffi.from_handle(udata) assert node dst_server = ffi.from_handle(lib.raft_node_get_udata(node)) server.network.enqueue_msg(msg, server, dst_server) # Collect statistics if server.network.max_entries_in_ae < msg.n_entries: server.network.max_entries_in_ae = msg.n_entries return 0
def raft_log(raft, node, udata, buf): server = ffi.from_handle(lib.raft_get_udata(raft)) # print(server.id, ffi.string(buf).decode('utf8')) if node != ffi.NULL: node = ffi.from_handle(lib.raft_node_get_udata(node)) # if server.id in [1] or (node and node.id in [1]): logging.info('{0}> {1}:{2}: {3}'.format( server.network.iteration, server.id, node.id if node else '', ffi.string(buf).decode('utf8'), ))
def send_snapshot(self, node): assert not lib.raft_snapshot_is_in_progress(self.raft) node_sv = ffi.from_handle(lib.raft_node_get_udata(node)) # TODO: Why would this happen? # seems odd that we would send something to a node that didn't exist if not node_sv: return 0 # NOTE: # In a real server we would have to send the snapshot file to the # other node. Here we have the convenience of the transfer being # "immediate". node_sv.load_snapshot(self.snapshot, self) return 0
def raft_send_requestvote(raft, udata, node, msg): server = ffi.from_handle(udata) dst_server = ffi.from_handle(lib.raft_node_get_udata(node)) server.network.enqueue_msg(msg, server, dst_server) return 0