Beispiel #1
0
class FifoNode(object):
    
    def __init__(self):
        self.fifoStats = None
        self.nodeIloop = None

    def getDest(self, msg):
        m = cPickle.loads(msg[1])
        return m[MsgType.DST]
    
    def updateFifoStats(self, dest, msg, tx=False, rx=False):
        key = repr((self.name, dest))
        if tx == True:
            if key not in self.fifoStats.tx.keys():
                self.fifoStats.tx[key] = []
            self.fifoStats.tx[key].append(msg)
        elif rx == True:
            if key not in self.fifoStats.rx.keys():
                self.fifoStats.rx[key] = []
            self.fifoStats.rx[key].append(msg)
            

    def procPeerTxServerMsg(self, stream, msg, status):
        
        logging.debug(str(msg))
        dst = self.getDest(msg)
        logging.debug("\tServer replying to: "+str(dst))
        logging.debug(str(msg))
        self.updateFifoStats(dst, msg, tx=True)


    def ackAgent(self, satisfy=False):

        
        prNodeStatus = self.prMod.getStatus()
        prNodeStatusMsg = PRStatusUpdate.createStatusUpdate(MsgType.PR_STATUS_UPDATE,
                                                           prNodeStatus[0],
                                                           prNodeStatus[1],
                                                           prNodeStatus[2],
                                                           prNodeStatus[3],
                                                           satisfy)
        logging.debug("\t[PR-LOG] ACK-AGENT3")
        logging.debug("\t[PR-LOG] Sending Status update to Agent ("+str(prNodeStatus[0])+")")
        
        
        #self.streamCmdOut.send_multipart([self.name, prNodeStatusMsg], callback=self.cmdOutRequestToSink)
        #self.streamCmdOut.flush()
        
        self.stupidVerificationSocket.send_multipart([self.name, prNodeStatusMsg])
        updateAck = self.stupidVerificationSocket.recv_multipart()
        logging.debug( str(updateAck))
        updateAck = cPickle.loads(updateAck[1])
        logging.debug( str(updateAck))
        assert prNodeStatus[0] == updateAck[PRStatusUpdate.SEQ]

        logging.debug("AfterQueue")
        logging.debug("Update ACK \t"+str(updateAck))
        logging.debug("PrNodeStatus \t"+str(prNodeStatus))
        
    
    def procPeerRxPathReversalMsg(self, stream, rxMsg, sender, pureMsg):
        
        logging.debug("\t[PR-LOG] Sending PR_ACK to:"+str(sender))
        ackMsg = MsgFactory.create(MsgType.PR_ACK, dst=sender)
        stream.send_multipart([self.name, ackMsg])

        
        if rxMsg[MsgType.DST] != self.name:
            if rxMsg[MsgType.TYPE] == MsgType.PR_REQ:
                logging.debug("\t[PR-LOG] Forwarding PR_REQ to:"+self.neighbor)
            elif rxMsg[MsgType.TYPE] == MsgType.PR_OBJ:
                logging.debug("\t[PR-LOG] Forwarding PR_OBJ to:"+self.neighbor)
            self.peerCltStream.send_multipart([self.name, pureMsg])
                
        elif rxMsg[MsgType.DST] == self.name:
            
            if rxMsg[MsgType.TYPE] == MsgType.PR_REQ:
            
                txMsg = None
                logging.debug("\t[PR-LOG] PR_REQ reached DST")
                action, actionArg = self.prMod.recv(self.name, rxMsg)
                
                self.ackAgent()
                                                                   
                if action == PRNext.FORWARD:
                    logging.debug("\t[PR-LOG] New Request FWD to:"+actionArg)
                    txMsg = MsgFactory.create(MsgType.PR_REQ, 
                                          dst=actionArg, 
                                          src=rxMsg[MsgType.SOURCE])
                    
                elif action == PRNext.TX_OBJ:
                    logging.debug("\t[PR-LOG] Serving OBJECT to:"+rxMsg[MsgType.SOURCE])
                    txMsg = MsgFactory.create(MsgType.PR_OBJ, 
                                          dst=rxMsg[MsgType.SOURCE],
                                          data=actionArg,  
                                          src=self.name)
                                            
                self.peerCltStream.send_multipart([self.name, txMsg])
                
            elif rxMsg[MsgType.TYPE] == MsgType.PR_OBJ:
                logging.debug("\t[PR-LOG] Received OBJECT from:"+rxMsg[MsgType.SOURCE])
                self.prMod.becomeEating(rxMsg[MsgType.DATA])
                
                logging.debug("\t[PR-LOG] Inform the server about EATING")
                self.ackAgent(satisfy=True)

            
    def procPeerRxServerMsg(self, stream, msg):
        logging.debug("\tReceived message...")
        rxMsg = cPickle.loads(msg[1])
        logging.debug("GENERIC:\t"+str(rxMsg))
            
        if rxMsg[MsgType.TYPE] == MsgType.PR_REQ or \
            rxMsg[MsgType.TYPE] == MsgType.PR_OBJ:
            self.procPeerRxPathReversalMsg(stream, rxMsg, msg[0], msg[1])            
            
                
        if rxMsg[MsgType.TYPE] == MsgType.KEEP_ALIVE:
            logging.debug('\tReceived KEEP_ALIVE message from:\t'+str(msg[0]))
            logging.debug('\tSending a KEEP_ALIVE_ACK message to:\t'+str(msg[0]))
            msgOut = MsgFactory.create(MsgType.KEEP_ALIVE_ACK, msg[0])
            try:
                stream.send_multipart([self.name, msgOut])
            except TypeError as e:
                logging.debug(e.message())

        if rxMsg[MsgType.TYPE] == MsgType.DATA_MSG:    
            did = rxMsg[MsgType.DATA_ID]
            logging.debug('\tReceived DATA_MSG message from:\t'+str(msg[0])+
                          " with id\t"+did)
            msgOut = MsgFactory.create(MsgType.DATA_ACK, None, None, did, None)
            logging.debug('\tSending DATA_ACK message to:\t'+str(msg[0]))
            stream.send_multipart([self.name, msgOut])
           
        
            if rxMsg[MsgType.DST] == self.name:    
                self.dataObject = deepcopy(rxMsg[MsgType.DATA])
                self.dataObjectId = rxMsg[MsgType.DATA_ID]
                logging.debug('\t[PR-LOG]DATA_MSG destination reached with id:'+
                               str(self.dataObjectId))
                logging.debug('\tSending DATA_ACK to Agent')
                msgOutDatAck = MsgFactory.create(MsgType.DATA_ACK, None, None, did, None)
                self.streamCmdOut.send_multipart([self.name, msgOutDatAck])
                    
            else:
                logging.debug("\tIncoming DATA_MSG needs forwarding")
                logging.debug("\tForwarding DATA_MSG("+str(did)+") to neighbor:\t"+
                              str(self.neighbor))
                self.peerCltStream.send_multipart([self.name, msg[1]])
                    
                    
    def procPeerTxClientMsg(self, msg, status):
        randomWaitOnFifo = choice(xrange(3))
        sleep(randomWaitOnFifo)
        dst = self.getDest(msg)
        logging.debug("Client sending: "+str(msg))
        self.updateFifoStats(dst, msg, tx=True)
    
    def procPeerRxClientMsg(self, msg):
        
        if len(msg) > 1:
            rxMsg = cPickle.loads(msg[1])
            self.updateFifoStats(msg[0], msg, rx=True)
            
            if rxMsg[MsgType.TYPE] == MsgType.KEEP_ALIVE_ACK:
                logging.debug("\tReceived KEEP_ALIVE_ACK from:\t"+str(msg[0]))
                    
            if rxMsg[MsgType.TYPE] == MsgType.DATA_ACK:
                logging.debug("\tReceived DATA_MSG_ACK from:\t"+
                            str(msg[1])+"\t for:\t"+str(rxMsg[MsgType.DATA_ID]))
   
            if rxMsg[MsgType.TYPE] == MsgType.PR_ACK:
                logging.debug("\t[PR-LOG] Received ACK for PR-REQ/PR_OBJ")
   
    def ackOrForward(self, msgIn, caseExisting=False, caseNACK=False):
        
        did = msgIn[MsgType.DATA_ID]
        if msgIn[MsgType.DST] == self.name or caseNACK == True:
            if caseNACK == False:
                msgOut = MsgFactory.create(MsgType.DATA_ACK, dataId=did)
                logging.debug("\tObject\t"+str(did)+" is home. Sending ACK to the agent")
            else:
                msgOut = MsgFactory.create(MsgType.DATA_NACK, dataId=did)
                logging.debug("\t Object\t"+str(did)+" is NOT home. Sending NACK to the agent")
                
            self.streamCmdOut.send_multipart([self.name, msgOut])
            self.streamCmdOut.flush()
            
            
        else:
            if caseExisting == True:
                msgIn[MsgType.TYPE] = MsgType.DATA_MSG
                
            msgOut = [self.name, cPickle.dumps(msgIn)]
            logging.debug("\tIncoming DATA_MSG needs forwarding")
            logging.debug("\tForwarding DATA_MSG("+str(did)+") to neighbor:\t"+
                          str(self.neighbor))
            self.peerSockClt.send_multipart(msgOut)
            
            
    def procAgentCmd(self, stream, msg):
        
        
        if msg[0] == 'Exit':
            logging.debug("Received exit")
            stream.stop_on_recv()
            self.nodeIloop.stop()
        
        if msg[0] == 'ConnectToNeighbor':
            logging.debug("\tConnectingToNeighbor  CMD arrived")
            self.peerSockClt = self.context.socket(zmq.REQ)
            self.peerSockClt.connect(self.neighborAddr)
            self.peerCltStream = zmqstream.ZMQStream(self.peerSockClt)
            self.peerCltStream.on_recv(self.procPeerRxClientMsg)
            self.peerCltStream.on_send(self.procPeerTxClientMsg)
       
        if  msg[0] == 'TestConnectionToNeighbor':
            logging.debug('\tTestConnection With the Peer-Neighbor')
            msgOut = MsgFactory.create(MsgType.KEEP_ALIVE,
                                       self.neighbor)
            self.peerSockClt.send_multipart([self.name, msgOut])   
        
        if msg[0] == 'Reset':
            logging.debug('\tServer send RESET message')
            self.prMod.reset()
        
        if msg[0] == 'Echo':
            logging.debug("\t Server sends echo message: "+(str(msg[1])))
        
        if msg[0] == 'Set':
            logging.debug('\tServer send SET message')
            rxMsg = cPickle.loads(msg[1])
            itemHolder = rxMsg[MsgType.DST]
            item = None
            if itemHolder == self.name:
                logging.debug("\tInitial object holder from Server's SET")
                item = rxMsg[MsgType.DATA]
                
            if self.prMod == None:
                self.prMod = PathReversal(itemHolder, item, logging)
            else:
                self.prMod.set(itemHolder,item, logging)
        
        if len(msg) > 1:
            rxMsg = cPickle.loads(msg[1])
            
            if rxMsg[MsgType.TYPE] == MsgType.AGENT_TEST_MSG:
                logging.debug('\tReceived Test from Agent')
                msgOut = MsgFactory.create(MsgType.AGENT_TETS_ACK)
                self.streamCmdOut.send_multipart([self.name, msgOut], callback=self.cmdOutRequestToSink)
            
            elif rxMsg[MsgType.TYPE] == MsgType.DATA_MOVE_MSG:
                logging.debug("Received DATA_MOVE_MSG request")
                if self.dataObjectId == rxMsg[MsgType.DATA_ID]:
                    self.ackOrForward(rxMsg, caseExisting=True)
                else:
                    self.ackOrForward(rxMsg, caseExisting=True, caseNACK=True)
                    
            elif rxMsg[MsgType.TYPE] == MsgType.DATA_MSG:
                logging.debug('\t[PR-LOG]Received Data Message from Agent with ID:\t'+
                              str(rxMsg[MsgType.DATA_ID]))
                self.ackOrForward(rxMsg, caseExisting=False)
            
            elif rxMsg[MsgType.TYPE] == MsgType.FIFO_STATS_QUERY:
                logging.debug("\tReceived FIFO-query-stats message from agent")
                self.streamCmdOut.send_multipart([self.name, cPickle.dumps(self.fifoStats)])
            
            elif rxMsg[MsgType.TYPE] == MsgType.PR_GET_HUNGRY:
                logging.debug("\tReceived Message from server to get hungry")
                txMsg, toWhom = self.prMod.becomeHungry(self.name)
                self.ackAgent()
                if txMsg != False:
                    logging.debug("\t[PR-LOG] Sending PR-Request to: "+toWhom)
                    self.peerCltStream.send_multipart([self.name, txMsg])
            
            elif rxMsg[MsgType.TYPE] == MsgType.PR_STATUS_ACK:
                logging.debug("======Incoming status ACK")
                
                print "======Incoming status ACK"
                self.statusQueue.put(rxMsg)
            
                    
        return
        
    def cmdOutRequestToSink(self, msg, status):
        logging.debug("[RequestToSink]\t"+str(msg))
    
    def cmdOutReplyFromSink(self, msg):
        logging.debug("[ReplyFromSink]\t"+str(msg))
        
    def runFifoNetWorker(self, netName, pubAgentAddr, sinkAgentAddr, neighbor):
    
        self.dataObject = None
        self.dataObjectId = None
        ioloop.install()
        self.prMod = None
        self.nodeIloop = ioloop.IOLoop.instance()
        self.statusQueue = Queue()
        
        self.fifoStats = FifoStats()
        
        logFname = netName.replace(":", "_")
        logFname = "logs/"+logFname
        logging.basicConfig(level=logging.DEBUG, filename=logFname)
        
        self.name = netName
        self.pubAgent = pubAgentAddr
        self.sinkAgent = sinkAgentAddr
        
        self.neighborAddr = "tcp://"+neighbor
        self.neighbor = neighbor
    
        logging.debug("\tCreating SubAgent socket")
        self.context = zmq.Context()
        self.cmdSubSock = self.context.socket(zmq.SUB)
        self.cmdSubSock.setsockopt(zmq.SUBSCRIBE, netName)
        self.cmdSubSock.setsockopt(zmq.SUBSCRIBE, b'Exit')
        self.cmdSubSock.setsockopt(zmq.SUBSCRIBE, b'ConnectToNeighbor')
        self.cmdSubSock.setsockopt(zmq.SUBSCRIBE, b'TestConnectionToNeighbor')
        self.cmdSubSock.setsockopt(zmq.SUBSCRIBE, b'Reset')
        self.cmdSubSock.setsockopt(zmq.SUBSCRIBE, b'Set')
        self.cmdSubSock.setsockopt(zmq.SUBSCRIBE, b'Echo')
        
        self.cmdSubSock.connect(self.pubAgent)
        self.streamCmdIn = zmqstream.ZMQStream(self.cmdSubSock)
        self.streamCmdIn.on_recv_stream(self.procAgentCmd)
        
        
        logging.debug("\tCreating PUSH-to-Agent socket")
        self.cmdReqRepSock = self.context.socket(zmq.REQ)
        self.cmdReqRepSock.connect(self.sinkAgent)
        self.streamCmdOut = zmqstream.ZMQStream(self.cmdReqRepSock)
        self.streamCmdOut.on_send(self.cmdOutRequestToSink)
        
        self.stupidVerificationSocket =  self.context.socket(zmq.REQ)
        self.stupidVerificationSocket.connect(self.sinkAgent)
        
        
        logging.debug("\tCreating Local Server socket")
        self.peerSockServ = self.context.socket(zmq.REP)
        localbindAddr = "tcp://*:"+netName.split(':')[1]
        self.peerSockServ.bind(localbindAddr)
        self.peerServStream = zmqstream.ZMQStream(self.peerSockServ)
        self.peerServStream.on_recv_stream(self.procPeerRxServerMsg)
        self.peerServStream.on_send_stream(self.procPeerTxServerMsg)
        
        
        self.nodeIloop.start()
Beispiel #2
0
 def procAgentCmd(self, stream, msg):
     
     
     if msg[0] == 'Exit':
         logging.debug("Received exit")
         stream.stop_on_recv()
         self.nodeIloop.stop()
     
     if msg[0] == 'ConnectToNeighbor':
         logging.debug("\tConnectingToNeighbor  CMD arrived")
         self.peerSockClt = self.context.socket(zmq.REQ)
         self.peerSockClt.connect(self.neighborAddr)
         self.peerCltStream = zmqstream.ZMQStream(self.peerSockClt)
         self.peerCltStream.on_recv(self.procPeerRxClientMsg)
         self.peerCltStream.on_send(self.procPeerTxClientMsg)
    
     if  msg[0] == 'TestConnectionToNeighbor':
         logging.debug('\tTestConnection With the Peer-Neighbor')
         msgOut = MsgFactory.create(MsgType.KEEP_ALIVE,
                                    self.neighbor)
         self.peerSockClt.send_multipart([self.name, msgOut])   
     
     if msg[0] == 'Reset':
         logging.debug('\tServer send RESET message')
         self.prMod.reset()
     
     if msg[0] == 'Echo':
         logging.debug("\t Server sends echo message: "+(str(msg[1])))
     
     if msg[0] == 'Set':
         logging.debug('\tServer send SET message')
         rxMsg = cPickle.loads(msg[1])
         itemHolder = rxMsg[MsgType.DST]
         item = None
         if itemHolder == self.name:
             logging.debug("\tInitial object holder from Server's SET")
             item = rxMsg[MsgType.DATA]
             
         if self.prMod == None:
             self.prMod = PathReversal(itemHolder, item, logging)
         else:
             self.prMod.set(itemHolder,item, logging)
     
     if len(msg) > 1:
         rxMsg = cPickle.loads(msg[1])
         
         if rxMsg[MsgType.TYPE] == MsgType.AGENT_TEST_MSG:
             logging.debug('\tReceived Test from Agent')
             msgOut = MsgFactory.create(MsgType.AGENT_TETS_ACK)
             self.streamCmdOut.send_multipart([self.name, msgOut], callback=self.cmdOutRequestToSink)
         
         elif rxMsg[MsgType.TYPE] == MsgType.DATA_MOVE_MSG:
             logging.debug("Received DATA_MOVE_MSG request")
             if self.dataObjectId == rxMsg[MsgType.DATA_ID]:
                 self.ackOrForward(rxMsg, caseExisting=True)
             else:
                 self.ackOrForward(rxMsg, caseExisting=True, caseNACK=True)
                 
         elif rxMsg[MsgType.TYPE] == MsgType.DATA_MSG:
             logging.debug('\t[PR-LOG]Received Data Message from Agent with ID:\t'+
                           str(rxMsg[MsgType.DATA_ID]))
             self.ackOrForward(rxMsg, caseExisting=False)
         
         elif rxMsg[MsgType.TYPE] == MsgType.FIFO_STATS_QUERY:
             logging.debug("\tReceived FIFO-query-stats message from agent")
             self.streamCmdOut.send_multipart([self.name, cPickle.dumps(self.fifoStats)])
         
         elif rxMsg[MsgType.TYPE] == MsgType.PR_GET_HUNGRY:
             logging.debug("\tReceived Message from server to get hungry")
             txMsg, toWhom = self.prMod.becomeHungry(self.name)
             self.ackAgent()
             if txMsg != False:
                 logging.debug("\t[PR-LOG] Sending PR-Request to: "+toWhom)
                 self.peerCltStream.send_multipart([self.name, txMsg])
         
         elif rxMsg[MsgType.TYPE] == MsgType.PR_STATUS_ACK:
             logging.debug("======Incoming status ACK")
             
             print "======Incoming status ACK"
             self.statusQueue.put(rxMsg)
         
                 
     return