def _hbeat(self, _): """ Local "beat" message-type """ if self.is_child: return if self._termSent or self._shutdown_initiated: return if self._term: Bus.publish(self, "%log", "warning", "SIGTERM received, Main Proc") Bus.publish(self, "shutdown") self._shutdown_initiated=True if not self._subToAlive: if self._ready: self._subToAlive=True Bus.subscribe("alive", self._halive) ### Make sure we have a response from each of the ### Child processes within the Time Interval self._beat_count=self._beat_count+1 if self._beat_count == self.BEATS_THRESHOLD: self._beat_count=0 if len(self.alives) != len(self._procs): Bus.publish(self, "%log", "warning", "child process(es) missing") Bus.publish(self, "%bark", self.pname) Bus.publish(self, "shutdown") self._shutdown_initiated self.alives=[]
def __init__(self, name): Process.__init__(self) self.pqueue=Queue() self.name=name self.term=False self.bark=False self._shutdown=False Bus.subscribe("%bark", self._hbark) Bus.subscribe("_sigterm", self._hsigterm) ## Publish the proc's details over the local message bus ## The ProcessManager will need those details in order to ## launch the process later on. Bus.publish(self, "proc", {"proc":self, "name":name, "queue":self.pqueue})
def run(self): """ Called by the multiprocessing module once the process is ready to run i.e. after the "fork" We intercept this call in order to make the final preparation before handing the control to the user process """ ## For now, there isn't that much to do ## except to reset the process level Message Bus ## to a known start state Bus.reset() Bus.subscribe("_ready", self._hready) ## Announce to the Agents we are starting and, incidentally, ## that "we" are a "Child" process Bus.publish(self, "proc_starting", (self.name, self.pqueue)) Bus.subscribe("beat", self._hbeat) Bus.subscribe("shutdown", self._hshutdown) return self.doRun()
Bus.publish(self, "_sigterm", self.pname) def _hproc_starting(self, (pname, _)): self._beat_count=0 self.is_child=True self.pname=pname signal.signal(signal.SIGTERM, self._sterm) ### Only subscribe to the signals ### when we know we are a Child process Bus.subscribe("beat", _cwd._hbeat) Bus.subscribe("%beat", _cwd._hlbeat) _cwd=Child_WatchDogAgent() Bus.subscribe("proc_starting", _cwd._hproc_starting) class Main_WatchDogAgent(object): BEATS_THRESHOLD = 3 def __init__(self): self.pname="__main__" self._subToAlive=False self._ready=False self.alives=[] self.is_child=False
proc.update(procDetails) self._procs[name]=proc def _hstart(self): """ Handler for "start" message marking the debut of all registered processes """ for proc_name in self._procs: procDetails=self._procs[proc_name] try: proc=procDetails["proc"] except: raise RuntimeError("procDetails require a `proc` entry") try: Bus.publish(self, "%log", "< starting process(%s)" % procDetails["name"]) proc.start() Bus.publish(self, "%log", "> started process(%s)" % procDetails["name"]) except Exception,e: raise RuntimeError("Exception whilst starting process (%s)" % e) ## ====================================================================================== ## ====================================================================================== _pm=ProcessManager() Bus.subscribe("start", _pm._hstart) Bus.subscribe("proc", _pm._hproc) Bus.subscribe("pname?", _pm._qpname) Bus.subscribe("proc_starting", _pm._hproc_starting)
def hready(self): print "TestProcRx (%s) ready!" % self.name self.ready=True Bus.subscribe("tick", self._htick)
def run(self): while not self._exitFlag: try: Bus.publish(None, "mswitch_pump") except Exception,e: print "*** (MAIN) Comm Exception!" Bus.publish(None, "log", "*** (MAIN) Comm exception: %s" % e) break print "MAIN pid(%s)" % os.getpid() Bus.publish(None, "%log", "main pid(%s)" % os.getpid()) p1=TestProc("proc1") p2=TestProc("proc2") p3=TestProc("proc3") p4=TestProc("proc4") pr1=TestProcRx("procRx1") pr2=TestProcRx("procRx2") _mainProc=MainProc() Bus.subscribe("shutdown", _mainProc._hshutdown) Bus.subscribe("%bark", _mainProc._hbark) Bus.publish(None, "start") _mainProc.run() print "***MAIN FINISHING" sys.exit()
self._logger.setLevel(logging.INFO) def _hlogpath(self, name, path): self._path = path self._name = name self._setup() def _hlog(self, *arg): if self._shutdown: return if self._logger is None: self._setup() if len(arg) == 1: self._logger.log(logging.INFO, arg[0]) else: level = self.mlevel.get(arg[0], logging.INFO) self._logger.log(level, arg[1]) def _hshutdown(self, *arg): self._shutdown = True self._logger = None logging.shutdown([self.fhdlr]) _log = Logger() Bus.subscribe("%log", _log._hlog) Bus.subscribe("logpath", _log._hlogpath) Bus.subscribe("shutdown", _log._hshutdown)
def _tick(self): self._beat=True ## atomic assignment def _qbeat(self): if self._beat: if self._child: Bus.publish(self, "%beat", self.pname) else: Bus.publish(self, "beat", self.pname) self._beat=False ## atomic assignment _heart=HeartAgent() Bus.subscribe("%beat?", _heart._qbeat) Bus.subscribe("proc_starting", _heart._hproc_starting) ## ===================================================== if __name__=="__main__": from time import sleep Bus.debug=True class Cb(object): def beat(self, state):
def _getQueue(self, pname): try: details=self._procs[pname] except: raise RuntimeError("missing proc from proc list") try: q=details["queue"] except: raise RuntimeError("missing `queue` parameter for proc(%s)" % pname) return q ## =============================================================================== ## =============================================================================== _mswitch=MessageSwitch() Bus.subscribe("*", _mswitch._promiscuousHandler) Bus.subscribe("_sigterm", _mswitch._hsigterm) Bus.subscribe("_sub", _mswitch._hsub) Bus.subscribe("proc", _mswitch._hproc) Bus.subscribe("_ready", _mswitch._hready) Bus.subscribe("mswitch_pump", _mswitch._hpump) Bus.subscribe("mswitch_params", _mswitch._hparams) Bus.subscribe("proc_starting", _mswitch._hproc_starting)