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
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)
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
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")