def retrieve(self, name): """ Retrieve value based on key, if not found locall send to successor to find it """ self.addMessage("retrieving: " + name) HashName = int(hashlib.sha1(name.encode('UTF-8')).hexdigest(), 16) if self.isItMine(self.id, self.predecessorID, HashName): self.addMessage("it is MINE in GUI: " + str(HashName)) try: value = self.SavedValues[HashName] if value: retrieveMessage = "OK "+ str(value) + "\r\n" self.addMessage(retrieveMessage) return value except: retrieveMessage = "Not Found " + "\r\n" self.addMessage(retrieveMessage) return -1 else: retrieveMessage = "Retrieve " + str(HashName) + "\r\n" chordSocketR = ChordSocket() chordSocketR.connect(self.successorID, self.successorPort) chordSocketR.chordsend(retrieveMessage) retMessage = chordSocketR.chordreceive() if self.getCommand(retMessage) == "Retrieve": self.addMessage("Message Received for Retrieve ") chordSocketR.sock.close() return 1
def join(self, host, port): """ Join to the network host: where is a node running port: on which port it is running """ self.addMessage("Joining host: " + host + " at port: " + port) chordSocket = ChordSocket() chordSocket.connect(host, int(port)) ## construct a Join -message bSend = "JOIN " + str(self.id) + " " + self.ipadr + " " + str(self.myport) + "\r\n" self.addMessage("Sending this JOIN message to node: " + bSend) chordSocket.chordsend(bSend) retMessage = chordSocket.chordreceive() self.addMessage("Received this message as reply for JOIN: " + retMessage) if self.getCommand(retMessage) == "JOIN_OK": lrLines = retMessage.split("\r\n") ## first three values are the new predecessor npID = int(lrLines[0].split(" ")[1]) npIP = str(lrLines[0].split(" ")[2]) npPO = int(lrLines[0].split(" ")[3]) ## and the next three values are my new successor nsID = int(lrLines[0].split(" ")[4]) nsIP = str(lrLines[0].split(" ")[5]) nsPO = int(lrLines[0].split(" ")[6]) self.successorID = nsID self.successorIP = nsIP self.successorPort = nsPO self.predecessorID = npID self.predecessorIP = npIP self.predecessorPort = npPO ## need to send NEWNODE message to our predecessor chordSocketn = ChordSocket() chordSocketn.connect(self.predecessorIP, int(self.predecessorPort)) nnMessage = "NEWNODE " + str(self.id) + " " + self.ipadr + " " + str(self.myport) + "\r\n" self.addMessage("Sending this NEWNODE to predecessor: " + self.predecessorIP + ":" + str(self.predecessorPort) + " - " + nnMessage) chordSocketn.chordsend(nnMessage) chordSocketn.sock.close() chordSocket.sock.close() return 1
def handleServerMessage(self, msg, clientsocket): """ reveive message from the Chord Server Thread. msg: is a string that has \r\n separated lines clientsocket: if we need to reply something, we use that """ self.addMessage("Received Message from Server Thread with: " + msg) ## first, split the message into lines, it's CRLF separated lLines = msg.split("\r\n") ## TODO: is this info really needed? self.addMessage(lLines) ## then we determine the command from first line sCommand = lLines[0].split(" ")[0] ## TODO: do we really want to log everything in stdout print(lLines) print(sCommand) if sCommand == "NEWNODE": ## NEWNODE, we just update our successor with new info ## no reply nnID = int(lLines[0].split(" ")[1]) nnIP = str(lLines[0].split(" ")[2]) nnPO = int(lLines[0].split(" ")[3]) self.successorID = nnID self.successorIP = nnIP self.successorPort = nnPO clientsocket.close() return 1 self.addMessage(sCommand) if sCommand == "JOIN": ## we got JOIN message from Server ## we need to determine if joining us, or forward to next ## it looks lit this ## JOIN 5147385592596484592 127.0.0.1 9002 ## so below the [1] number is the field (indexed from 0) nnID = int(lLines[0].split(" ")[1]) nnIP = str(lLines[0].split(" ")[2]) nnPO = int(lLines[0].split(" ")[3]) ## so either we send back our self or ask our successor if self.isItMine(self.id, self.predecessorID, nnID): ## we have determined tat we are the point to connect to, update our own ## info and send JOIN_OK back ## JOIN_OK. This message is sent by the node which received the JOIN and ##confirms the success of JOIN to the new node. As arguments, JOIN_OK has ##the identifier, the IP address, and port of the predecessor and the ##identifier, the IP address, and port of the successor for the new node (the ##successor is the node sending JOIN_OK and the predecessor is that node ##current predecessor). JOIN_OK will be immediately followed by a ##TRANSFER@message which transfers the key@value pairs which are now ##the responsibility of the new nod retMessageS = self.getJOIN_OK_and_Update(nnID, nnIP, nnPO) retMessageS = retMessageS + "\r\n" self.addMessage(retMessageS) chordSocketS = ChordSocket(clientsocket) chordSocketS.chordsend(retMessageS) clientsocket.close() return 1 else: ## we determinet that this is not the point to JOIN, so we pass ## the message to our successor as such, wait for reply and ## pass what ever reply we got to the reply - works recursively ## from one node to another chordSocketS = ChordSocket() chordSocketS.connect(self.successorIP, int(self.successorPort)) bSendS = msg chordSocketS.chordsend(bSendS) retMessageS = chordSocketS.chordreceive() self.addMessage(retMessageS) chordSocketS = ChordSocket(clientsocket) chordSocketS.chordsend(retMessageS) clientsocket.close() return 1 elif sCommand == "JOIN_OK": return 1 ##server never get's a JOIN_OK message in this way elif sCommand == "LEAVE": ## somebody is leaving, update our PREDECESSOR from the LEAVE message self.predecessorID = int(lLines[0].split(" ")[1]) self.predecessorIP = str(lLines[0].split(" ")[2]) self.predecessorPort = int(lLines[0].split(" ")[3]) clientsocket.close() return 1 elif sCommand == "NODEGONE": ## reveived NODEGONE, update our SUCCESSOR accordingly self.successorID = int(lLines[0].split(" ")[1]) self.successorIP = str(lLines[0].split(" ")[2]) self.successorPort = int(lLines[0].split(" ")[3]) clientsocket.close() return 1 elif sCommand == "TRANSFER": ## received TRANSFER ## TODO update our dictionary self.addMessage("TRANSFER " + lLines[0]) clientsocket.close() return 1 elif sCommand == "STORE": ## received STORE message, either STORE here or pass ## to the successor HashName = int(lLines[0].split(" ")[1]) value = int(lLines[0].split(" ")[2]) if self.isItMine(self.id, self.predecessorID, HashName): self.SavedValues[HashName] = value else: chordSocketSTO = ChordSocket() chordSocketSTO.connect(self.successorIP, self.successorPort) sStore= "STORE " + " "+ name + " : " + value + "\r\n" chordSocketSTO.chordsend(sStore) chordSocketSTO.sock.close() elif sCommand == "RETRIEVE": ## received RETRIEVE, either see if should found locally and try to find ## or send to successor for search HashName = int(lLines[0].split(" ")[1]) if self.isItMine(self.id, self.predecessorID, HashName): try: value = self.SavedValues[HashName] if value: retrieveMessage = "OK "+ str(value) + "\r\n" self.addMessage(retrieveMessage) clientsocket.close() return value except: retrieveMessage = "Not Found " + "\r\n" self.addMessage(retrieveMessage) clientsocket.close() return -1 else: retrieveMessage = "Retrieve " + HashName + "\r\n" chordSocketR = ChordSocket() chordSocketR.connect(self.successorID, self.successorPort) chordSocketR.chordsend(retrieveMessage) retMessage = chordSocketR.chordreceive() if self.getCommand(retMessage) == "Retrieve": self.addMessage("Message Received for Retrieve ") chordSocketR.sock.close() return 1