예제 #1
0
    def sequncer_multicast(self, id):
        m = SqeuncerMessage(id, self.s_sequencer.value)

        for to_pid in self.process_info.keys():
            self.unicast(m, to_pid)

        with self.s_sequencer.get_lock():
            self.s_sequencer.value += 1
예제 #2
0
    def recv(self, data, from_addr):
        if data:
            data_args = data.split()

            """
                Multicast Message
            """
            if len(data_args) == 4:
                from_id, to_id, id, message = int(data_args[0]), int(data_args[1]), int(data_args[3]), data_args[2]
                # ack get message
                print("get message %s from %d" % (message, from_id))

                m = TotalOrderMessage(from_id, to_id, id, message)

                # push the message in to queue
                self.hb_queue.append(m)

                # If the receiving process is sequencer, multicast the sequencer message to all the other processes
                if self.is_sequencer:
                    self.sequencer_multicast(id)

                # check our sequence message to queue to see if we already received the corresponding sequence message
                self.check_seq_queue(self.r_sequencer.value)
            """
                Sequencer's order message
            """
            elif len(data_args) == 2:
                m_id, sequence = int(data_args[0]), int(data_args[1])
                seq_m = SqeuncerMessage(m_id, sequence)
                message = self.check_queue(m_id)

                # if the sequence order is expected and we already received the message
                if sequence == self.r_sequencer.value and message:

                    # Deliver the message to process
                    unicast_receive(message.from_id, message)

                    # update the value of sequence number
                    with self.r_sequencer.get_lock():
                        self.r_sequencer.value += 1

                    # check our sequence message queue to see
                    # if we already received a sequence message with higher sequence number
                    self.check_seq_queue(self.r_sequencer.value)

                # if the sequence number is not what we expected or we haven't received the corresponding message
                # then we save them into the queue for later use.
                else:
                    self.seq_queue.append(seq_m)
                    if message:
                        self.hb_queue.append(message)

            # Unicast Receive
            else:
                m = Message(data_args[0], data_args[1], data_args[2])
                self.process.unicast_receive(m.from_id, m)
예제 #3
0
    def sequencer_multicast(self, id):
        """
            SqeuncerMessage(randMessageID, s_sequencer.value)
        """
        m = SqeuncerMessage(id, self.s_sequencer.value)

        for to_pid in self.process_info.keys():
            self.unicast(m, to_pid)
        # increment sequencer order number
        with self.s_sequencer.get_lock():
            self.s_sequencer.value += 1
예제 #4
0
    def recvReplica(self, data):
        print("recvReplica...")
        # print("dump all keys in messageID2client: ")
        # self.lock.acquire()
        # for key in self.messageID2client: print(key)
        # self.lock.release()

        if data:
            print("get replica message ", data)
            data_args = data.split()
            """
                r_ack(var, value, timepoint, messageID)
            """
            if (data_args[0] == "r_ack"):
                # data = 'r_ack 2 2 x 0 0 8037938055510234267 980486'
                from_id, to_id, var, value, timepoint, id, client_id = int(
                    data_args[1]), int(data_args[2]), data_args[3], int(
                        data_args[4]), int(data_args[5]), int(
                            data_args[6]), int(data_args[7])
                # update var timpoint and value
                if (timepoint > self.variables.lastWrite[var]):
                    self.variables.lastWrite[var] = timepoint
                    self.variables.variables[var] = value
                # update received ack
                self.variables.setRAck(var, self.variables.getRAck(var) + 1)

                # send r_ack to client if received ack >= R
                if (self.variables.getRAck(var) >= self.R):
                    self.lock.acquire()
                    if id in self.messageID2client:
                        conn = self.messageID2client[id]
                        ack_message = var + " " + str(
                            self.variables.variables[var])
                        m = EventualConsistencyMessage(self.pid, client_id, id,
                                                       client_id, ack_message,
                                                       "r_ack")
                        self.unicastTCP(self.pid, m, conn)
                        # clean received ack
                        self.variables.setRAck(var, 0)
                        self.printLog(m, self.variables.lastWriteTime(var))
                    else:
                        print("no corresponded messageID %d" % (id))
                    self.lock.release()

            # w_ack(var, messageID)
            elif (data_args[0] == "w_ack"):
                # data = 'w_ack 33276 2 put x 1 7440523501060122809 33276'
                from_id, to_id, tok, var, value, id, client_id = int(
                    data_args[1]), int(
                        data_args[2]), data_args[3], data_args[4], int(
                            data_args[5]), int(data_args[6]), int(data_args[7])
                self.variables.setWAck(var, self.variables.getWAck(var) + 1)
                if (self.variables.w_ack[var] >= self.W):
                    self.lock.acquire()
                    if id in self.messageID2client:
                        conn = self.messageID2client[id]
                        ack_message = var + " " + str(
                            self.variables.variables[var])
                        # m = "w_ack from_id message_id message_id message message_id"
                        m = EventualConsistencyMessage(self.pid, client_id, id,
                                                       client_id, ack_message,
                                                       "w_ack")
                        self.unicastTCP(self.pid, m, conn)
                        # clean received ack
                        self.variables.setWAck(var, 0)
                        self.printLog(m, self.variables.lastWriteTime(var))
                    else:
                        print("no corresponded messageID %d" % (id))
                    self.lock.release()
            # write(var,value)
            # total order multicast
            elif (data_args[0] == "w"):
                # data = 'w 1 1 17701 put x 1 990784337849110725'
                from_id, to_id, tok, var, value, id, client_id = int(
                    data_args[1]), int(
                        data_args[2]), data_args[3], data_args[4], int(
                            data_args[5]), int(data_args[6]), int(data_args[7])
                message = tok + " " + var + " " + str(value)
                m = EventualConsistencyMessage(from_id, to_id, id, client_id,
                                               message, "w")
                # push the message in to queue
                self.hb_queue.append(m)

                # If the receiving process is sequencer,
                # multicast the sequencer message to all the other processes
                if self.is_sequencer:
                    self.sequencer_multicast(id)

                # check our sequence message to queue to see if we already received the corresponding sequence message
                self.check_seq_queue(self.r_sequencer.value)

            # read(var) Message
            # deliver immediately without total order multicast
            elif (data_args[0] == "r"):
                # data = 'r 2 2 103533 get x 1342189802441044593 54641'
                from_id, to_id, tok, var, id, client_id = int(
                    data_args[1]), int(
                        data_args[2]), data_args[3], data_args[4], int(
                            data_args[5]), int(data_args[6])
                # deliver message
                print("deliver message %s from %d" % (data, from_id))

                timepoint = self.variables.lastWriteTime(var)
                value = self.variables.variables[var]
                ack_message = var + " " + str(value) + " " + str(timepoint)

                # only sender print log
                if (from_id == self.pid):
                    ack_log = var + " " + str(value)
                    m_log = EventualConsistencyMessage(from_id, to_id, id,
                                                       client_id, ack_log, "r")
                    self.printLog(m_log, timepoint)

                # ack_message = "r_ack var value timepoint messageID"
                m = EventualConsistencyMessage(from_id, to_id, id, client_id,
                                               ack_message, "r_ack")
                self.unicast(m, from_id)

            # Sequencer's order message
            elif (data_args[0] == "seq"):
                m_id, sequence = int(data_args[1]), int(data_args[2])
                self.messageID2timestamp[m_id] = sequence
                seq_m = SqeuncerMessage(m_id, sequence)

                # only 'w' message has 'seq'
                # message = self.messageID2message[m_id]
                # self.printLog(message, sequence)
                message = self.check_queue(m_id)

                # if the sequence order is expected and we already received the message
                if sequence == self.r_sequencer.value and message:

                    # Deliver the message to process
                    self.deliver(message.from_id, message, sequence)

                    # update the value of sequence number
                    with self.r_sequencer.get_lock():
                        self.r_sequencer.value += 1

                    # check our sequence message queue to see
                    # if we already received a sequence message with higher sequence number
                    self.check_seq_queue(self.r_sequencer.value)

                # if the sequence number is not what we expected or we haven't received the corresponding message
                # then we save them into the queue for later use.
                else:
                    self.seq_queue.append(seq_m)
                    if message:
                        self.hb_queue.append(message)

            # Unicast Receive
            else:
                print("replica message not understood")
                # m = Message(data_args[0], data_args[1], data_args[2])
                # self.process.unicast_receive(m.from_id, m)
        else:
            print("No data received from replica")