示例#1
0
    def poll_message(self, msg):
        msg_type = ffi.getctype(ffi.typeof(msg.data))

        if msg_type == 'msg_appendentries_t *':
            node = lib.raft_get_node(msg.sendee.raft, msg.sendor.id)
            response = ffi.new('msg_appendentries_response_t*')
            e = lib.raft_recv_appendentries(msg.sendee.raft, node, msg.data, response)
            if lib.RAFT_ERR_SHUTDOWN == e:
                logging.error('Catastrophic')
                print(msg.sendee.debug_log())
                print(msg.sendor.debug_log())
                sys.exit(1)
            elif lib.RAFT_ERR_NEEDS_SNAPSHOT == e:
                pass  # TODO: pretend as if snapshot works
            else:
                self.enqueue_msg(response, msg.sendee, msg.sendor)

        elif msg_type == 'msg_appendentries_response_t *':
            node = lib.raft_get_node(msg.sendee.raft, msg.sendor.id)
            lib.raft_recv_appendentries_response(msg.sendee.raft, node, msg.data)

        elif msg_type == 'msg_requestvote_t *':
            response = ffi.new('msg_requestvote_response_t*')
            node = lib.raft_get_node(msg.sendee.raft, msg.sendor.id)
            lib.raft_recv_requestvote(msg.sendee.raft, node, msg.data, response)
            self.enqueue_msg(response, msg.sendee, msg.sendor)

        elif msg_type == 'msg_requestvote_response_t *':
            node = lib.raft_get_node(msg.sendee.raft, msg.sendor.id)
            e = lib.raft_recv_requestvote_response(msg.sendee.raft, node, msg.data)
            if lib.RAFT_ERR_SHUTDOWN == e:
                msg.sendor.shutdown()

        else:
            assert False
示例#2
0
 def notify_membership_event(self, node, event_type):
     # Convenience: Ensure that added node has udata set
     if event_type == lib.RAFT_MEMBERSHIP_ADD:
         node_id = lib.raft_node_get_id(node)
         try:
             server = self.network.id2server(node_id)
         except ServerDoesNotExist:
             pass
         else:
             node = lib.raft_get_node(self.raft, node_id)
             lib.raft_node_set_udata(node, server.udata)
示例#3
0
    def load_snapshot(self, snapshot, other):
        # logging.warning('{} loading snapshot'.format(self))
        e = lib.raft_begin_load_snapshot(
            self.raft,
            snapshot.last_term,
            snapshot.last_idx,
        )
        if e == -1:
            return 0
        elif e == lib.RAFT_ERR_SNAPSHOT_ALREADY_LOADED:
            return 0
        elif e == 0:
            pass
        else:
            assert False

        # Send appendentries response for this snapshot
        response = ffi.new('msg_appendentries_response_t*')
        response.success = 1
        response.current_idx = snapshot.last_idx
        response.term = lib.raft_get_current_term(self.raft)
        response.first_idx = response.current_idx
        self.network.enqueue_msg(response, self, other)

        node_id = lib.raft_get_nodeid(self.raft)

        # set membership configuration according to snapshot
        for member in snapshot.members:
            if -1 == member.id:
                continue

            node = lib.raft_get_node(self.raft, member.id)

            if not node:
                udata = ffi.NULL
                try:
                    node_sv = self.network.id2server(member.id)
                    udata = node_sv.udata
                except ServerDoesNotExist:
                    pass

                node = lib.raft_add_node(self.raft, udata, member.id, member.id == node_id)

            lib.raft_node_set_active(node, 1)

            if member.voting and not lib.raft_node_is_voting(node):
                lib.raft_node_set_voting(node, 1)
            elif not member.voting and lib.raft_node_is_voting(node):
                lib.raft_node_set_voting(node, 0)

            if node_id != member.id:
                assert node

        # TODO: this is quite ugly
        # we should have a function that removes all nodes by ourself
        # if (!raft_get_my_node(self->raft)) */
        #     raft_add_non_voting_node(self->raft, NULL, node_id, 1); */

        e = lib.raft_end_load_snapshot(self.raft)
        assert(0 == e)
        assert(lib.raft_get_log_count(self.raft) == 0)

        self.do_membership_snapshot()
        self.snapshot.image = dict(snapshot.image)
        self.snapshot.last_term = snapshot.last_term
        self.snapshot.last_idx = snapshot.last_idx

        assert(lib.raft_get_my_node(self.raft))
        # assert(sv->snapshot_fsm);

        self.fsm_dict = dict(snapshot.image)

        logging.warning('{} loaded snapshot t:{} idx:{}'.format(
            self, snapshot.last_term, snapshot.last_idx))