Example #1
0
 def causal(self, cmds):
     if cmds.request == 1:  # write request coming from primary/master
         newKV = cmds.data.split(" ::: ")
         if len(newKV) == 2:
             self.causalDB[newKV[0]] = newKV[1]
             self.writeTimestamp = max(self.writeTimestamp, cmds.l_Clock)
             toMaster = build_msg.build(self.ip, cmds.consis, cmds.request,
                                        1, cmds.data, cmds.l_Clock,
                                        cmds.rID)
             self.start_connections(
                 self.master_ip, toMaster.SerializeToString(
                 ))  # not even sure master needs to see this
     elif cmds.request == 2:  # read request coming from causalClient
         if self.writeTimestamp > cmds.ma_Timestamp:  # if we have seen the relevant write, we can reply
             if cmds.data in self.causalDB:
                 toMaster = build_msg.build(self.ip, cmds.consis,
                                            cmds.request, 1,
                                            self.causalDB[cmds.data],
                                            cmds.l_Clock, cmds.rID)
             else:
                 toMaster = build_msg.build(self.ip, cmds.consis,
                                            cmds.request, 0,
                                            'Key not found', cmds.l_Clock,
                                            cmds.rID)
         else:  # returning something here would break causal consistency
             toMaster = build_msg.build(self.ip, cmds.consis, cmds.request,
                                        0, 'Try get request later',
                                        cmds.l_Clock, cmds.rID)
         self.start_connections(self.master_ip,
                                toMaster.SerializeToString())
Example #2
0
    def eventual(self, cmds):
        pass
        toMaster = msg_pb2.Message()
        if cmds.rID in self.requests.keys():
            # Do nothing if replica has already seen request
            pass
        else:
            # Handle set request
            if cmds.request == 1:
                newKV = cmds.data.split(" ::: ")
                if len(newKV) == 2:

                    self.allConsisDB[newKV[0]] = newKV[1]
                    self.eventualDB[newKV[0]] = newKV[1]

                    # If msg from master,
                    # then it is the first replica to see it, and we should send a response
                    if cmds.ip == config.MASTER_IP:
                        toMaster = build_msg.build(self.ip, cmds.consis,
                                                   cmds.request, cmds.ack,
                                                   cmds.data, cmds.l_Clock,
                                                   cmds.rID)

                    # Send to other replicas if
                    for ip in self.replicaRoster:
                        if ip == self.ip:
                            pass
                        else:
                            toReplica = build_msg.build(
                                self.ip, cmds.consis, cmds.request, cmds.ack,
                                cmds.data, cmds.l_Clock, cmds.rID)
                            self.start_connections(
                                ip, toReplica.SerializeToString())

                    # Add the request to the requests dictionary
                    self.requests[cmds.rID] = cmds.ip

                else:
                    toMaster = build_msg.build(self.ip, cmds.consis,
                                               cmds.request, 0, cmds.data,
                                               cmds.l_Clock, cmds.rID)

            # Handle get request
            elif cmds.request == 2:
                if cmds.data in self.eventualDB:
                    pass
                    toMaster = build_msg.build(self.ip, cmds.consis,
                                               cmds.request, 1,
                                               self.eventualDB[cmds.data],
                                               self.l_clock, cmds.rID)
                else:
                    toMaster = build_msg.build(self.ip, cmds.consis,
                                               cmds.request, 0, 'Get Failure',
                                               self.l_clock, cmds.rID)

            # Send off to master
            self.start_connections(self.master_ip,
                                   toMaster.SerializeToString())
Example #3
0
    def run(self):  #override node run method
        self.lsock.bind((self.ip, config.PORT))
        self.lsock.listen()
        self.node_log.write('listening on' + str((self.ip, config.PORT)))
        self.lsock.setblocking(False)
        self.sel.register(self.lsock, selectors.EVENT_READ, data=None)

        for message in messages:

            #self.l_clock += 1
            print(self.role + ' sent a request!')
            msg = build_msg.build(self.ip, message[0], message[1], 1,
                                  message[2], self.l_clock)
            self.start_connections(self.master_ip, msg.SerializeToString())
            #time.sleep(0.1)

        print('Client is running')

        try:
            while True:
                events = self.sel.select(timeout=None)
                for key, mask in events:
                    if key.data is None:
                        self.accept_wrapper(key.fileobj)
                    else:
                        self.service_connection(key, mask)
        except KeyboardInterrupt:
            print("caught keyboard interrupt, node exiting")
            self.node_log.write('Logical clock:' + str(self.l_clock))
            self.node_log.output_log()
        finally:
            self.sel.close()
Example #4
0
    def run(self):  #override node run method
        self.lsock.bind((self.ip, config.PORT))
        self.lsock.listen()
        self.node_log.write('listening on' + str((self.ip, config.PORT)))
        self.lsock.setblocking(False)
        self.sel.register(self.lsock, selectors.EVENT_READ, data=None)
        #msg = msg_pb2.Message()
        msg = build_msg.build(self.ip, 0, 0, 0, 'hey there Im up',
                              self.l_clock)
        self.node_log.write('\n Data outbound: \n')
        self.node_log.write(str(msg))
        self.start_connections(self.master_ip, msg.SerializeToString())
        print('im running!')
        #print('my l clock is : ' + str(self.l_clock))
        try:
            while True:
                events = self.sel.select(timeout=None)
                for key, mask in events:
                    if key.data is None:
                        self.accept_wrapper(key.fileobj)
                    else:
                        self.service_connection(key, mask)
        except KeyboardInterrupt:
            print("caught keyboard interrupt, node exiting")
            self.node_log.write('Logical clock:' + str(self.l_clock))

            self.node_log.write('Outstanding requests:' + '\n')
            for req in self.requests:
                if (isinstance(self.requests[req], PriorityQueue)):
                    self.node_log.write('\n' + str(req) + ': ' +
                                        str(self.requests[req].queue))
                else:
                    self.node_log.write('\n' + str(req) + ': ' +
                                        str(self.requests[req]))
            self.node_log.write('processed requests:' + '\n')
            for req in self.processed_reqs:
                if (isinstance(self.processed_reqs[req], PriorityQueue)):
                    self.node_log.write('\n' + str(req) + ': ' +
                                        str(self.processed_reqs[req].queue))
                else:
                    self.node_log.write('\n' + str(req) + ': ' +
                                        str(self.processed_reqs[req].queue))

            self.node_log.write("\nLinearPQ: " + str(self.linearPQ.queue))
            self.node_log.write("\nSeqPQ: " + str(self.seqPQ.queue))
            self.node_log.write("\nAll consistencies DB : " +
                                str(self.allConsisDB))
            self.node_log.write("Linearized consistency DB : " +
                                str(self.linearDB))
            self.node_log.write("Sequential consistency DB : " +
                                str(self.sequentialDB))
            self.node_log.write("Causal consistency DB : " +
                                str(self.causalDB))
            self.node_log.write("Eventual consistency DB : " +
                                str(self.eventualDB))
            self.node_log.output_log()
        finally:
            self.sel.close()
    def run(self):  #override node run method
        self.lsock.bind((self.ip, config.PORT))
        self.lsock.listen()
        self.node_log.write('listening on' + str((self.ip, config.PORT)))
        self.lsock.setblocking(False)
        self.sel.register(self.lsock, selectors.EVENT_READ, data=None)
        for message in messages:

            # if read message, calculate minimum acceptable timestamp
            if message[1] == 2:
                if message[2] in self.writes:
                    wt = self.writes[message[2]]
                else:
                    wt = 0
                ma_Timestamp = max(wt, self.read_time)
                msg = build_msg.build(self.ip,
                                      3,
                                      message[1],
                                      1,
                                      message[2],
                                      self.l_clock,
                                      ma_Timestamp=ma_Timestamp)
            else:
                msg = build_msg.build(self.ip, 3, message[1], 1, message[2],
                                      self.l_clock)
            self.start_connections(self.master_ip, msg.SerializeToString())
            #time.sleep(0.1)

        print('Client is running')

        try:
            while True:
                events = self.sel.select(timeout=None)
                for key, mask in events:
                    if key.data is None:
                        self.accept_wrapper(key.fileobj)
                    else:
                        self.service_connection(key, mask)
        except KeyboardInterrupt:
            print("caught keyboard interrupt, node exiting")
            self.node_log.write('Logical clock:' + str(self.l_clock))
            self.node_log.output_log()
        finally:
            self.sel.close()
Example #6
0
    def tob(self, cmds):
        msgQ = PriorityQueue()
        outb = msg_pb2.Message()

        #check if request is in the dict
        if (cmds.rID in self.requests.keys()):
            # this is an acknowledgement message
            #add to request's msgQ
            msgQ = self.requests[cmds.rID]
            msgQ.put((msgQ.queue[0][0] + cmds.l_Clock, cmds))
            #update requests dict
            self.requests[cmds.rID] = msgQ

        else:
            #this is a command message
            #update local requests dict
            if (cmds.ip == self.master_ip):
                outb = build_msg.build(self.ip, cmds.consis, cmds.request, 1,
                                       cmds.data, self.l_clock, cmds.rID)
                #msgQ.put((self.l_clock, outb))
                self.requests[cmds.rID] = msgQ

                if (cmds.consis == 1):
                    # add to linearPQ
                    self.linearPQ.put((self.l_clock, cmds.rID, cmds))
                else:
                    # add to seq
                    self.seqPQ.put((self.l_clock, cmds.rID, cmds))
                self.broadcast(outb)
                return 0

            else:
                # handle replica message
                msgQ.put((cmds.l_Clock, cmds))
                self.requests[cmds.rID] = msgQ

                if (cmds.consis == 1):
                    # add to linearPQ
                    self.linearPQ.put((cmds.l_Clock, cmds.rID, cmds))
                else:
                    # add to seq
                    self.seqPQ.put((cmds.l_Clock, cmds.rID, cmds))
        self.broadcast(cmds)
Example #7
0
    def broadcast(self, cmds):
        #logging where we are with our requests
        ''' 
        for req in self.requests:
            if(isinstance(self.requests[req], PriorityQueue)):
                self.node_log.write('\n' + str(req) + ': ' + str(self.requests[req].queue)) 
            else:
                self.node_log.write('\n' + str(req) + ': ' + str(self.requests[req])) 
        self.node_log.write('processed requests:' + '\n') 
        for req in self.processed_reqs:
            if(isinstance(self.processed_reqs[req], PriorityQueue)):
                self.node_log.write('\n' + str(req) + ': ' + str(self.processed_reqs[req].queue))
            else: 
                self.node_log.write('\n' + str(req) + ': ' + str(self.processed_reqs[req].queue)) 
        '''
        # Check the queues if we have any broadcasting to do
        # if linear
        if (cmds.consis == 1):
            #prevent empty queue
            if (len(self.linearPQ.queue) == 0):
                self.node_log.write('**Lin Queue is Empty ****!!!!')
                return 0
            rID = self.linearPQ.queue[0][1]
            orig_msg = self.linearPQ.queue[0][2]
            msgQ = self.requests[rID]
            top_msg = msg_pb2.Message()
            outb = msg_pb2.Message()
            #self.node_log.write('\n' + 'message q: \n' + str(msgQ.queue))
            for msg in msgQ.queue:
                if (msg[1].ip == self.ip and len(msgQ.queue) < 3):
                    #we have already sent a message
                    return 0
            # are we the originator of the next queued broadcast
            if (len(msgQ.queue) == 0):
                outb = build_msg.build(self.ip, orig_msg.consis,
                                       orig_msg.request, 1, orig_msg.data,
                                       self.linearPQ.queue[0][0], orig_msg.rID)
                #update msgQ and requests
                msgQ.put((self.linearPQ.queue[0][0], outb))
                self.requests[rID] = msgQ
                # Broadcast to all
                for ip in self.replicaRoster:
                    if ip == self.ip:
                        pass
                    else:
                        self.start_connections(ip, outb.SerializeToString())
                self.broadcast(cmds)
                return 0

            top_msg = msgQ.queue[0][1]
            # all acks are in and we are originator
            if (len(msgQ.queue) == len(self.replicaRoster)):
                #remove first element
                self.linearPQ.get()
                #if set perform operation
                if (top_msg.request == 1):
                    newKV = top_msg.data.split(" ::: ")
                    if (len(newKV) == 2):
                        self.node_log.write('\n' + 'processing: ' +
                                            str(newKV) + '\n')
                        self.allConsisDB[newKV[0]] = newKV[1]
                        self.linearDB[newKV[0]] = newKV[1]
                        outb = build_msg.build(self.ip, 1, 1, 1,
                                               'Set successful', self.l_clock,
                                               rID)
                    else:
                        outb = build_msg.build(self.ip, 1, 1, 0, 'Set failure',
                                               self.l_clock, rID)

                else:
                    # perform get
                    if (top_msg.data in self.linearDB):
                        outb = build_msg.build(self.ip, orig_msg.consis,
                                               orig_msg.request, 1,
                                               self.linearDB[orig_msg.data],
                                               self.l_clock, orig_msg.rID)
                    else:
                        outb = build_msg.build(self.ip, orig_msg.consis,
                                               orig_msg.request, 0,
                                               'Get Failure', self.l_clock,
                                               orig_msg.rID)
                #if we are originator send to master
                if (top_msg.ip == self.ip):
                    self.start_connections(self.master_ip,
                                           outb.SerializeToString())

                #move request to processed_reqs
                self.processed_reqs[rID] = self.requests.pop(rID)
                #call broadcast again to check if we need to do anything
                self.broadcast(cmds)
            else:

                #These should all be requests that we are not originators on
                #check if we need to broadcast ack
                #if(len(msgQ.queue) == 1):
                # Broadcast to all
                for ip in self.replicaRoster:
                    if ip == self.ip:
                        pass
                    else:
                        outb = build_msg.build(self.ip, top_msg.consis,
                                               top_msg.request, top_msg.ack,
                                               'acknowledge ' + top_msg.data,
                                               self.l_clock, top_msg.rID)
                        #update msg queue and send ack
                        self.start_connections(ip, outb.SerializeToString())
                clock = 0
                clock = self.l_clock + self.linearPQ.queue[0][0]
                msgQ.put((clock, outb))
                self.requests[rID] = msgQ
                self.broadcast(cmds)

        else:

            #sequential tob
            if (len(self.seqPQ.queue) == 0):
                self.node_log.write('**Seq Queue is Empty ****!!!!')
                return 0

            rID = self.seqPQ.queue[0][1]
            orig_msg = self.seqPQ.queue[0][2]
            msgQ = self.requests[rID]
            top_msg = msg_pb2.Message()
            outb = msg_pb2.Message()

            if (orig_msg.request == 2):
                #If the next message in the queue is a get, just do it
                if (top_msg.data in self.sequentialDB):
                    outb = build_msg.build(self.ip, orig_msg.consis,
                                           orig_msg.request, 1,
                                           self.sequentialDB[orig_msg.data],
                                           self.l_clock, orig_msg.rID)
                else:
                    outb = build_msg.build(self.ip, orig_msg.consis,
                                           orig_msg.request, 0, 'Get Failure',
                                           self.l_clock, orig_msg.rID)

                #Remove from queue, send to master, then broadcast again
                fillQueue = PriorityQueue()
                fillQueue.put((rID, orig_msg))
                self.seqPQ.get()
                self.requests.pop(rID)  # remove from requests registry
                self.processed_reqs[rID] = fillQueue
                self.start_connections(self.master_ip,
                                       outb.SerializeToString())
                self.broadcast(cmds)

            else:

                #self.node_log.write('\n' + 'message q: \n' + str(msgQ.queue))
                for msg in msgQ.queue:
                    if (msg[1].ip == self.ip and len(msgQ.queue) < 3):
                        #we have already sent a message
                        return 0
                # are we the originator of the next queued broadcast
                if (len(msgQ.queue) == 0):
                    outb = build_msg.build(self.ip, orig_msg.consis,
                                           orig_msg.request, 1, orig_msg.data,
                                           self.seqPQ.queue[0][0],
                                           orig_msg.rID)
                    #update msgQ and requests
                    msgQ.put((self.seqPQ.queue[0][0], outb))
                    self.requests[rID] = msgQ
                    # Broadcast to all
                    for ip in self.replicaRoster:
                        if ip == self.ip:
                            pass
                        else:
                            self.start_connections(ip,
                                                   outb.SerializeToString())
                    self.broadcast(cmds)
                    return 0

                top_msg = msgQ.queue[0][1]
                # all acks are in and we are originator
                if (len(msgQ.queue) == len(self.replicaRoster)):
                    #remove first element
                    self.seqPQ.get()
                    #if set perform operation
                    newKV = top_msg.data.split(" ::: ")
                    if (len(newKV) == 2):
                        self.node_log.write('\n' + 'processing: ' +
                                            str(newKV) + '\n')
                        self.allConsisDB[newKV[0]] = newKV[1]
                        self.sequentialDB[newKV[0]] = newKV[1]
                        outb = build_msg.build(self.ip, 1, 1, 1,
                                               'Set successful', self.l_clock,
                                               rID)
                    else:
                        outb = build_msg.build(self.ip, 1, 1, 0, 'Set failure',
                                               self.l_clock, rID)

                    #if we are originator send to master
                    if (top_msg.ip == self.ip):
                        self.start_connections(self.master_ip,
                                               outb.SerializeToString())

                    #move request to processed_reqs
                    self.processed_reqs[rID] = self.requests.pop(rID)
                    #call broadcast again to check if we need to do anything
                    self.broadcast(cmds)
                else:

                    #These should all be requests that we are not originators on
                    #check if we need to broadcast ack
                    #if(len(msgQ.queue) == 1):
                    # Broadcast to all
                    for ip in self.replicaRoster:
                        if ip == self.ip:
                            pass
                        else:
                            outb = build_msg.build(
                                self.ip, top_msg.consis, top_msg.request,
                                top_msg.ack, 'acknowledge ' + top_msg.data,
                                self.l_clock, top_msg.rID)
                            #update msg queue and send ack
                            self.start_connections(ip,
                                                   outb.SerializeToString())
                    clock = 0
                    clock = self.l_clock + self.seqPQ.queue[0][0]
                    msgQ.put((clock, outb))
                    self.requests[rID] = msgQ
                    self.broadcast(cmds)
Example #8
0
    def handle_message(self, cmds):
        #test message
        recv_ip = cmds.ip

        #TODO handle all possible incoming messages

        ### Handle Client message
        if recv_ip not in self.replicaRoster:
            if (cmds.request > 2):
                # TODO send error message to client 'faulty request'
                pass
            elif (
                    cmds.consis == 3 and cmds.request == 1
            ):  # causal consistency + write request -> lazy propagation -- send to all replicas
                self.currentRID += 1
                #self.requests[self.currentRID] = (cmds, time.time(), 0, 0)

                for r in self.replicaRoster:
                    toReplica = build_msg.build(self.ip, cmds.consis,
                                                cmds.request, cmds.ack,
                                                cmds.data, self.l_clock,
                                                self.currentRID)
                    self.start_connections(r, toReplica.SerializeToString())

                ## also, send a message back to client. It will update it's clock
            #  self.processed_reqs[cmds.rID] = (curr_req[0], curr_req[1], curr_time, proc_time)
                toClient = build_msg.build(self.ip, cmds.consis, cmds.request,
                                           cmds.ack, cmds.data, self.l_clock,
                                           self.currentRID)
                #self.processed_reqs[cmds.rID] = self.requests.pop(cmds.rID)
                self.start_connections(cmds.ip, toClient.SerializeToString())

            else:
                self.currentRID += 1
                # (rID, [orig_Message, timestamp recv, timestamp processed, total time elapsed])
                self.requests[self.currentRID] = (cmds, time.time(), 0, 0)

                #Message to send to replica
                toReplica = build_msg.build(self.ip, cmds.consis, cmds.request,
                                            cmds.ack, cmds.data, self.l_clock,
                                            self.currentRID, cmds.ma_Timestamp)

                #send to random? replica.
                self.start_connections(
                    self.replicaRoster[random.randrange(
                        0, len(self.replicaRoster))],
                    toReplica.SerializeToString())
                #time.sleep(0.5)

        ### Handle Replica message
        else:
            if cmds.rID != 0 and cmds.consis == 3 and cmds.request != 1:  # if it's a write, we don't need to do anything

                toClient = build_msg.build(self.ip, cmds.consis, cmds.request,
                                           cmds.ack, cmds.data, cmds.l_Clock,
                                           cmds.rID)

                try:
                    client = self.requests[cmds.rID][0].ip
                    self.processed_reqs[cmds.rID] = self.requests.pop(cmds.rID)

                    # calculate current time stats
                    curr_req = self.processed_reqs[cmds.rID]
                    curr_time = time.time()
                    proc_time = curr_time - curr_req[1]

                    #update processed_reqs
                    self.processed_reqs[cmds.rID] = (curr_req[0], curr_req[1],
                                                     curr_time, proc_time)

                    #finalize request by sending to client
                    #print('sent read confirm to client')
                    self.start_connections(client,
                                           toClient.SerializeToString())

                except:
                    print("an error occured in causal with cmd : " + str(cmds))
            elif cmds.rID != 0 and cmds.consis != 3:
                if cmds.ack == 1:
                    #Answer a successful request to client
                    toClient = build_msg.build(self.ip, cmds.consis,
                                               cmds.request, cmds.ack,
                                               cmds.data, self.l_clock,
                                               cmds.rID)

                elif cmds.ack == 0:
                    #Answer failure of Request to client
                    pass
                    toClient = build_msg.build(self.ip, cmds.consis,
                                               cmds.request, cmds.ack,
                                               'REQUEST FAILURE', self.l_clock,
                                               cmds.rID)

                try:
                    client = self.requests[cmds.rID][0].ip
                    self.processed_reqs[cmds.rID] = self.requests.pop(cmds.rID)

                    # calculate current time stats
                    curr_req = self.processed_reqs[cmds.rID]
                    curr_time = time.time()
                    proc_time = curr_time - curr_req[1]

                    #update processed_reqs
                    self.processed_reqs[cmds.rID] = (curr_req[0], curr_req[1],
                                                     curr_time, proc_time)

                    #finalize request by sending to client
                    self.start_connections(client,
                                           toClient.SerializeToString())

                except:
                    print("an error occured with cmd : " + str(cmds))