예제 #1
0
 def _cmdrun(self, *args, cmd=None, dest=None, source=None):
     """ Runs as a separate thread for taking care of commands."""
     try:
         if cmd == None: return
         value = cmd.run(*args)
         self.sendMsg(makeMsg(value,source,dest))
     except Exception as e:
         self.sendMsg(makeErrorMsg(str(e), source, dest))    
예제 #2
0
 def __sendToDaemon(self, msg):
     #send to daemon.
     logging.debug("sending to daemon")
     _,base=self._daemon
     if base is not None:
         if msg.getType() == COMMAND_MSG_TYPE:
             found = False
             for cmd in base.get_commands():
                 #logging.debug("comparing: %s ?= %s"%(cmd,msg.getValue()))
                 if cmd == msg.getValue():
                     found = True 
                     Thread(target=self._cmdrun, args=msg.get("args"),
                            kwargs={"cmd":cmd, "dest":msg.getSource(),
                                    "source":msg.getDestination()}).start()
             if not found:
                 self.sendMsg(makeErrorMsg("Command does not exist.",msg.getDestination(), msg.getSource() ))
         elif msg.getType() == ERROR_MSG_TYPE:
             logging.error("error from %s: %s" % (msg.getSource(), msg.getValue()))
         else: #alert or base we ignore
             pass
     else: logging.debug("should have sent the message to the base handler")
예제 #3
0
 def startRouter(self, triggermethod=lambda:False):
     """ This is the thread that runs and pushes messages everywhere. """
     
     logging.debug("ComRouter thread has started")
     while triggermethod():
         try:
             if self._msg_queue.empty():raise queue.Empty
             msg = self._msg_queue.get() #remove and return a message
             
             if isinstance(msg, str): 
                 msg = strToMessage(msg)
             elif msg is None or not isinstance(msg, Message): 
                 continue
             
             logging.debug("destination: %s"%msg.getDestination())
             
             # if the destination is not "registered" but its a known type
             if msg.getDestination() == "" or msg.getDestination() == None:
                 # Check if the message type is an alert, if it is, then send it
                 # to all interfaces and alerters. We keep this functionality for
                 # possible use in Chat programs or quick universal relays. But
                 # actual "Alerts" are now called Events and are managed by the
                 # EventManager.
                 if msg.getType() == ALERT_MSG_TYPE:
                     for id in list( self._routees.keys()):
                         logging.debug("sending alert to %s: %s"% (id, msg))
                         _,ref = self._routees.get(id)
                         if isinstance(ref, Interface):
                             Thread(target=ref.handle_msg, args=(msg,)).start()
                         # Notice, alarms don't get the message.
                         
                 # if not send it to the daemon to handle.
                 else:
                     self.__sendToDaemon(msg)
                         
             
             elif self.isRegistered(msg.getDestination()):
                 if msg.getDestination() == "daemon" or msg.getDestination() == None:
                     self.__sendToDaemon(msg)
                     continue
                 # if its registered, it could be a routee or an attachment.
                 if msg.getType() == COMMAND_MSG_TYPE:
                     cmds = self._attachments.getCommands(msg.getDestination())
                     if cmds is not None:#we can run the command and send the result.
                         found = False
                         for cmd in cmds:
                             if cmd == msg.getValue():
                                 found = True
                                 Thread(target=self._cmdrun, args=msg.get("args"),
                                        kwargs={"cmd":cmd, "dest":msg.getSource(),
                                                "source":msg.getDestination()}).start()
                         if not found:
                             self.sendMsg(makeErrorMsg("Command does not exist.",msg.getDestination(), msg.getSource() ))
                         continue   
                         
                 #ok to send since its been registered, but is a routee
                 ref = self._routees.get(msg.getDestination(),None)
                 if ref is not None:
                     logging.debug("sending message: %s" % msg)
                     Thread(target=ref.handle_msg, args=(msg,)).start()
                 else: #send to daemon.
                     self.__sendToDaemon(msg)
             
             # if we don't know how to handle the message, log and discard it. oh well.
             else:
                 logging.warning("I don't know who %s is, msg=%s" % 
                                 (msg.getDestination(), str(msg.getValue())))
                 
         except queue.Empty: pass
         except Exception as e:
             logging.exception(e)
 
         ## then we sleep for a while. This is randomized because we don't really know
         ## the speed at which messages are being sent. We could write a method to adapt
         ## to the internal rate, later. But currently randomizing provides a better 
         ## compensation than a constant time factor.
         if not self._msg_queue.empty(): continue
         try: time.sleep(random.random())
         except: pass
         
     #when closing, it doesn't need to clean anything, just die and 
     #log about it
     logging.debug("ComRouter thread has died")