Example #1
0
    def get_consistency_helper(self, key, socket, contact):
        msg = store.Msg()
        msg.pair_read.key = key
        msg.pair_read.val = self.keyValStore[key].split(":")[0]

        socket.sendall(msg.SerializeToString())

        response = socket.recv(1024)

        msg = store.Msg()
        if response:
            msg.ParseFromString(response)
            if msg.WhichOneof("msg") == "suc":
                if msg.suc.success == True:
                    self.OKs.append(True)
                else:
                    if self.const_mech == 0:
                        # do a read repair
                        self.RR_lock.acquire()
                        if self.handling_read_repair == False:
                            self.handling_read_repair = True
                            self.RR_lock.release()
                            self.read_repair(key)
                        else:
                            self.RR_lock.release()

        thread.exit()
Example #2
0
    def waitForInstruction(self):

        print("Waiting for coordinator <" + str(self.coordinator) +
              "> to assign a request")

        if (self.recoveryFlag):
            t = threading.Thread(target=self.attemptToConnect)
            t.start()
            t.join()

        #Hinted Handoff Consistency Mechanism
        if (self.const_mech == 1):

            self.performHintedHandoff()

        try:

            coordinatorSocket = self.neighborSockets[self.coordinator]

            time.sleep(2)

            msg = coordinatorSocket.recv(1024)

            store_msg = store.Msg()
            store_msg.ParseFromString(msg)
            msgType = store_msg.WhichOneof("msg")
            valid = self.parse_msg(coordinatorSocket, ("", ""), store_msg)

            if (valid == "False"):

                return

            elif (valid == "True"):

                msg = store.Msg()
                msg.suc.success = True
                coordinatorSocket.sendall(msg.SerializeToString())

        except (KeyboardInterrupt, OSError) as e:

            if self.clientSocket:

                self.clientSocket.close()
                self.clientSocket = None

            for sock in self.neighborSockets:

                if sock:
                    sock.close()
                    sock = None

            sys.exit()
Example #3
0
    def get(self, key, level, client_socket):

        consistency_worked = None

        if key in self.keyValStore:
            val_to_send = self.keyValStore[key].split(":")
            val_to_send = val_to_send[0]
            time_stamp = val_to_send[1]

            consistency_worked = self.get_consistency(key, level)
            msg_to_send = store.Msg()
            msg_to_send.string_val.val = val_to_send
            client_socket.sendall(msg_to_send.SerializeToString())

        else:
            #we contact the next replica in the ring
            msg_to_send = store.Msg()
            msg_to_send.suc.success = False

            client_socket.sendall(msg_to_send.SerializeToString())

            for i in range(4):
                if i == int(self.replica_num):
                    continue
                sock = self.neighborSockets[i]
                self.reset_msg(sock, 0)

            consistency_worked = True
            '''
            sock_to_contact = self.neighborSockets[(int(self.replica_num) + 1) % 4]
            msg_to_send = store.Msg()
            msg_to_send.get.key = key
            msg_to_send.get.level = level
            print("key is not in this node, asking next node...")
            sock_to_contact.sendall(msg_to_send.SerializeToString())
            val = sock_to_contact.recv(1024)
            if val:
                msg_to_respond = store.Msg()
                msg_to_respond.ParseFromString(val)
                if msg_to_respond.WhichOneof("msg") == "string_val":
                    msg = store.Msg()
                    msg.string_val.val = msg_to_respond.string_val.val
                    client_socket.sendall(msg.SerializeToString())
                    consistency_worked = True
            '''
        if consistency_worked == True:
            return
        else:
            # send a message to the client that it didn't work
            not_OK = store.Msg()
            not_OK.suc.success = False
            client_socket.sendall(not_OK.SerializeToString())
Example #4
0
    def retrieve_timestamp(self, key, socket):
        msg = store.Msg()
        msg.pair_read.key = key
        msg.pair_read.val = self.keyValStore[int(key)]
        socket.sendall(msg.SerializeToString())

        write_this = socket.recv(1024)
        #call pair_write

        if write_this:
            s = store.Msg()
            s.ParseFromString(write_this)
            if s.WhichOneof("msg") == "pair_write":
                self.pair_write(s.pair_write.key, s.pair_write.val)
Example #5
0
    def performHintedHandoff(self):

        msg = store.Msg()

        time.sleep(int(self.replica_num))

        if (len(self.hints[self.coordinator]) > 0):

            print("I have hints for the coordinator")

            k = []
            v = []
            for i in range(len(self.hints[self.coordinator])):

                k.append(self.hints[self.coordinator][i][0])
                v.append(self.hints[self.coordinator][i][1])

            msg.hint.hintKey.extend(k)
            msg.hint.hintValue.extend(v)

            print(self.hints[self.coordinator])
            self.hints[self.coordinator].clear()
            print(self.hints)

        else:

            print("No hints for the coordinator")
            noHint = []
            noHint.append(-1)
            noVal = []
            noVal.append("-")
            msg.hint.hintKey.extend(noHint)
            msg.hint.hintValue.extend(noVal)

        self.neighborSockets[self.coordinator].sendall(msg.SerializeToString())
Example #6
0
    def read_repair(self, key):
        begins = self.bytePartitioner(key)
        timestamps = {}  # replica num => timestamp
        msg = store.Msg()
        msg.timestamp.key = key
        for i in range(3):
            contact = (int(begins) + i) % 4
            if int(contact) == int(self.replica_num):
                continue

            socket = self.neighborSockets[contact]
            # we want to find out who has the latest version of the object
            socket.sendall(msg.SerializeToString())
            response = socket.recv(1024)
            parser = store.Msg()
            if response:
                parser.ParseFromString(response)
                if parser.WhichOneof("msg") == "pair_read":
                    timestamps[contact] = parser.pair_read.val

        #now that we have all the timestamps of all the replicas we have to compare the
        # timestamps
        timestamps[int(
            self.replica_num)] = self.keyValStore[key]  # add our own verison
        max_timestamp = 0
        max_val = ""
        for replica_num, val in timestamps.items():
            value, timestamp = val.split(":")
            timestamp = float(timestamp)
            if max_timestamp < timestamp:
                max_timestamp = timestamp
                max_val = value

        self.keyValStore[key] = max_val + ":" + str(time.time())

        read_repair_msg = store.Msg()
        read_repair_msg.pair_write.key = key
        read_repair_msg.pair_write.val = max_val

        for i in range(3):
            contact = (int(begins) + i) % 4
            if int(contact) == int(self.replica_num):
                continue
            socket = self.neighborSockets[contact]
            socket.sendall(read_repair_msg.SerializeToString())
Example #7
0
    def send_put_msg(self, key, val, consistency):
        msg = store_pb2.Msg()
        msg.put.key = key
        msg.put.val = val
        msg.put.level = consistency

        self.coordinatorSocket.sendall(msg.SerializeToString())

        val = self.coordinatorSocket.recv(1024)

        if val:

            s = store_pb2.Msg()
            s.ParseFromString(val)
            if (s.suc.success):

                print("Write operation completed successfully")

            else:

                print("Failed to write to replicas desired")
Example #8
0
    def send_get_req(self, key, consistency):
        msg = store_pb2.Msg()
        msg.get.key = key
        msg.get.level = consistency
        self.coordinatorSocket.sendall(msg.SerializeToString())
        val = self.coordinatorSocket.recv(1024)
        if val:
            s = store_pb2.Msg()
            s.ParseFromString(val)

            if s.WhichOneof("msg") == "string_val":
                value = s.string_val.val
                index = value.find("M") + 1
                print("Key: " + str(key) + " => " + value[index:])

            elif s.WhichOneof("msg") == "suc":
                self.sendInitialization(int(self.cur_coordinator) + 1)
                corIP = self.replicaList[self.cur_coordinator][0]
                cor_port = self.replicaList[self.cur_coordinator][1]
                self.coordinatorSocket = socket.socket(socket.AF_INET,
                                                       socket.SOCK_STREAM)
                self.coordinatorSocket.connect((corIP, cor_port))
                self.send_get_req(key, consistency)
Example #9
0
    def compare_pair(self, key, val, sock):

        msg = store.Msg()

        print(self.keyValStore)

        if key in self.keyValStore:

            if self.keyValStore[key].split(":")[0] == val:
                msg.suc.success = True
            else:
                msg.suc.success = False
        else:
            msg.suc.success = False

        sock.sendall(msg.SerializeToString())

        timestamp = sock.recv(1024)

        parser = store.Msg()
        parser.ParseFromString(timestamp)
        if parser.WhichOneof("msg") == "timestamp":
            self.retrieve_timestamp(key, sock)
Example #10
0
    def coordinatorFunction(self, client_sock, client_add, store_msg):

        if self.recoveryMode:

            for replica in reversed(self.replicaList):

                index = self.replicaList.index(replica)

                if (index == int(self.replica_num)):

                    continue

                else:

                    incomingConn, incomingAddr = self.clientSocket.accept()
                    '''

                        for every replica in replicaList

                            ip = replica[0].getIp()

                            if incomingAddr[0] == ip

                                self.neighborSockets[replicaList.index(replica)] = incomingConn

                    '''

                    self.neighborSockets[self.replicaList.index(
                        replica)] = incomingConn
                    print("Got connection from " + str(index) + ": {" +
                          incomingAddr[0] + ", " + str(incomingAddr[1]) + "}")
                    print("")

        #Wait to receive hints if consistency mechanism is hinted handoff
        if (self.const_mech == 1):

            self.receiveHintedHandoff(client_sock)

        infoMsg = client_sock.recv(1024)

        if infoMsg:

            store_msg = store.Msg()
            store_msg.ParseFromString(infoMsg)

        self.parse_msg(client_sock, client_add, store_msg)
Example #11
0
    def sendInitialization(self, coordinator):
        self.cur_coordinator = int(coordinator)

        for replica in replicaList:

            initSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

            try:

                initSocket.connect((replica))

            except:

                print("Can't connect")
                continue

            msg = store_pb2.Msg()
            msg.init.coordinator = coordinator

            initSocket.sendall(msg.SerializeToString())

        initSocket.close()
Example #12
0
    def receiveHintedHandoff(self, socket):

        print("")
        print("---------------Handling Hints---------------")
        print("")

        time.sleep(2)

        hintMessagesReceived = 0

        for socket in self.neighborSockets:

            if (self.neighborSockets.index(socket) == self.coordinator):
                continue
            else:
                msg = socket.recv(1024)
                if msg:

                    store_msg = store.Msg()
                    store_msg.ParseFromString(msg)
                    msgType = store_msg.WhichOneof("msg")

                    ret = self.parse_msg(socket, ("", ""), store_msg)
                    if (ret == "True"):
                        print("Got a hint from " +
                              str(self.neighborSockets.index(socket)))

                    elif (ret == "False"):
                        print("No hint from " +
                              str(self.neighborSockets.index(socket)))

        print(self.keyValStore)

        print("")
        print("-------------Done Handling Hints-------------")
        print("")
Example #13
0
    def run(self):

        self.clientSocket.bind(('', self.portNum))

        print("Starting Replica " + self.replica_num + ": {" + self.hostName +
              ":" + str(self.portNum) + "}")

        self.neighborSockets[int(self.replica_num)] = self.clientSocket

        self.clientSocket.listen(30)

        print("---------------Connecting All Replicas---------------")
        print("")

        if not self.recoveryMode:

            self.initializeNeighboringSockets()

        print("--------------Ready To Receive Requests--------------")

        #Check for write-log file
        writeLog = Path("./" + self.logName)
        if (writeLog.exists()):
            self.parseWriteLog()

        while True:

            client_sock = None
            client_add = None

            try:

                while (self.coordinator == -1):

                    try:

                        client_sock, client_add = self.clientSocket.accept()

                        msg = client_sock.recv(1024)

                        if msg:

                            store_msg = store.Msg()
                            store_msg.ParseFromString(msg)
                            msgType = store_msg.WhichOneof("msg")
                            self.parse_msg(client_sock, client_add, store_msg)

                    except KeyboardInterrupt or AttributeError:

                        if self.clientSocket:
                            self.clientSocket.close()

                        for sock in self.neighborSockets:

                            if sock:

                                sock.close()

                        break

                #Replica
                if (self.replica_num != str(self.coordinator)):

                    self.waitForInstruction()

                #coordinator
                else:

                    print("Connected to client as coordinator: {" +
                          client_add[0] + ":" + str(client_add[1]) + "}")

                    self.coordinatorFunction(client_sock, client_add,
                                             store_msg)

            except KeyboardInterrupt:

                for sock in self.neighborSockets:

                    if sock:
                        sock.close()

                if self.clientSocket:
                    self.clientSocket.close()

                break

            self.coordinator = -1
            client_sock.close()
Example #14
0
    def put(self, key, val, level, client_socket):

        #Determine how many replicas are needed before returning to client
        replicasForConsistency = level + 1

        #First replica determined by the byte partitioner
        firstReplica = self.bytePartitioner(key)

        #Second and third are clockwise in the cluster
        secondReplica = (firstReplica + 1) % 4
        thirdReplica = (firstReplica + 2) % 4

        operationReplicas = [firstReplica, secondReplica, thirdReplica]

        print("I will be storing this data on")
        print(
            str(firstReplica) + " " + str(secondReplica) + " " +
            str(thirdReplica))

        #Amount of replicas that have successfully completed the request
        successfulPuts = 0

        #Loop through all four replcias
        for i in range(4):

            #Send to only those replicas desired by coordinator
            if (i in operationReplicas):

                #Create message to send to replicas
                msg = store.Msg()
                msg.pair_write.key = key
                msg.pair_write.val = val

                index = operationReplicas.index(i)

                #This replica is required to store the info
                if (operationReplicas[index] == int(self.replica_num)):

                    #Write to log before adding to local memory

                    self.storeLock.acquire()

                    writeLogInfo = open(self.logName, "a")
                    writeLogInfo.write(
                        str(key) + ":" + val + ":" + str(time.time()) + "\n")
                    writeLogInfo.close()

                    self.keyValStore[key] = val

                    self.storeLock.release()

                    #"Put" was successful, return to client if consistency level is met
                    if key in self.keyValStore:

                        print("Added: " + val + " to location: " + str(key))
                        successfulPuts += 1

                        #We have reached QUORUM or ONE consistency
                        if (successfulPuts == replicasForConsistency):

                            msg_to_send = store.Msg()
                            msg_to_send.suc.success = True
                            client_socket.sendall(
                                msg_to_send.SerializeToString())

                    continue

                #Find socket connecting to other replica
                repSock = self.neighborSockets[operationReplicas[index]]
                time.sleep(0.5)

                #Send message containing key and val to replica
                try:

                    repSock.sendall(msg.SerializeToString())

                except socket.error:

                    self.neighborSockets[i].close()
                    print("Failed to connect to " + str(i))

                    if (self.const_mech == 1):
                        print("Storing <" + str(key) + val + "> as a hint")

                        self.hints[i].append((key, val))

                        print(self.hints)

                    continue

                #Sleep to see effect of consistency level
                time.sleep(2)

                #Receive response
                try:

                    msg = repSock.recv(1024)

                except socket.error:

                    self.neighborSockets[i].close()
                    print("Failed to connect to " + str(i))
                    if (self.const_mech == 1):
                        print("Storing <" + str(key) + val + "> as a hint")

                        self.hints[i].append((key, val))

                        print(self.hints)

                    continue

                store_msg = store.Msg()
                store_msg.ParseFromString(msg)
                msgType = store_msg.WhichOneof("msg")
                valid = self.parse_msg(repSock, ("", ""), store_msg)

                #The put in a replica was successful
                if (valid):

                    print("Successful copy to " +
                          str(operationReplicas[index]))

                    successfulPuts += 1

                    #We have enough for the consistency, send success to client
                    if (successfulPuts == replicasForConsistency):

                        msg_to_send = store.Msg()
                        msg_to_send.suc.success = True
                        client_socket.sendall(msg_to_send.SerializeToString())

                    continue

                else:

                    print("Failed copy to " + str(operationReplicas[index]))

                    #Append hint to list for replica that failed
                    self.neighborSockets[i].close()
                    print("Failed to connect to " + str(i))
                    if (self.const_mech == 1):
                        print("Storing <" + str(key) + val + "> as a hint")

                        self.hints[i].append((key, val))

                        print(self.hints)

                    continue

            #Message to get unused replcias out of the wait function
            else:

                if (i == int(self.replica_num)):
                    continue

                msg = store.Msg()
                msg.pair_write.key = -1
                msg.pair_write.val = "None"
                repSock = self.neighborSockets[i]
                time.sleep(0.5)
                repSock.sendall(msg.SerializeToString())

        #Send failure to client
        if (successfulPuts < replicasForConsistency):

            print("Didn't get to consistency level")

            msg_to_send = store.Msg()
            msg_to_send.suc.success = False
            client_socket.sendall(msg_to_send.SerializeToString())
Example #15
0
 def reset_msg(self, socket, contact):
     msg = store.Msg()
     msg.pair_write.key = -1
     msg.pair_write.val = ":)"
     socket.sendall(msg.SerializeToString())
     thread.exit()