def _scan(self): for pid in listProcesses(): try: AppProcess(Server(config.HOSTNAME), pid) except InvalidProcess: pass except IOError: pass #happens on linux when a pid dies except: err('process table scanning error') #scan for crashed instances for app in App.objects: if not app.__class__.isValid(app): continue for ai in app.localappinstances: if not ai.__class__.isValid(ai): continue if ai in self.tracking: continue if not self.first_run: #avoid process table races self.tracking.add(ai) config.reactor.callLater(SERVICECONFIG.recovery_period, self.tracking.discard, ai ) if not ai.enabled: continue #skip disabled result = None if ai.running and not ai.shouldBeRunning: ai.shouldBeRunning = True if ai.running: continue manager = AppManager(ai.app.name) if not manager.running: continue #skip managers that are not running if not manager.discover: continue #app manager claims to be ok #look for processes that we can assimilate d = manager.model.findProcesses() wfd = defer.waitForDeferred(d) yield wfd for (pid, result) in wfd.getResult(): d = manager.model.assimilateProcess(result) wfd2 = defer.waitForDeferred(d) yield wfd2 ai2 = wfd2.getResult() if ai2 and isinstance(ai2, AppInstance) and ai2 is ai: Event('instance-found').fire(instance=ai) manager.log('Sucessfully assimilated PID %d' % ai2.pid) if ai.running: continue #may have assimilated the app if not ai.crashed: continue if not ai.enabled: continue #disabled instances are not actionable if self.first_run: continue #avoid process table races Event('instance-crashed').fire(instance=ai) #cool off on eventing for a little while #keep the process objects up to date for process in AppProcess.objects: try: if not process.localInstall: continue if not process.running: AppProcess.delete(process) except: err('process book keeping error') d = defer.Deferred() config.reactor.callLater(0.01, d.callback, None) wfd = defer.waitForDeferred(d) yield wfd wfd.getResult() self.first_run = False yield 'done'
def ApplicationPluginAdaptToAppManager(self, app): """I adapt any L{IDroneDApplication} provider to a corresponding L{IDroneModelAppManager} provider. @return L{IDroneModelAppManager} provider """ return AppManager(app.name)
def startService(self): """Start All AppManager Services""" if self.scanning.called: #need to pre-populate values self.scanning = defer.maybeDeferred(self._first_scan) self.first_run = True self._task = task.LoopingCall(self.scan_app_instances) #plugins will be created and loaded when needed for shortname in config.APPLICATIONS.keys(): manager = None try: applog = logWithContext(type=shortname,route=SERVICENAME) applog('Loading Application Plugin') applog('Creating Application Manager') manager = AppManager(shortname) manager.parentService = self #check and see if the model is bound if not AppManager(shortname).running: applog('Starting Application Manager') manager.start() except: failure = Failure() #bad plugin, not adaptable failures = (InvalidPlugin, TypeError) if failure.check(*failures) and manager: log('plugin for %s is invalid' % (manager.name,)) manager.action.__class__.delete(manager.action) try: pluginFactory.delete_plugin(manager.model) except: pass #silence AppManager.delete(manager) if not config.EXCESSIVE_LOGGING: continue #avoid extra logging try: failure.raiseException() except: crashReport('ApplicationLoader', self) Service.startService(self) Event('instance-started').subscribe(self.reset_tracking) #wire allapps action into the server drone.builtins.update({ 'allapps': self.allapps_action, 'applist': self.applist_action, }) #delay scanning by some interval config.reactor.callLater(SERVICECONFIG.initial_delay, self._start_all_tasks)
def startService(self): """Start All AppManager Services""" if self.scanning.called: #need to pre-populate values self.scanning = defer.maybeDeferred(self._first_scan) self.first_run = True self._task = task.LoopingCall(self.scan_app_instances) #plugins will be created and loaded when needed for shortname in config.APPLICATIONS.keys(): manager = None try: applog = logWithContext(type=shortname, route=SERVICENAME) applog('Loading Application Plugin') applog('Creating Application Manager') manager = AppManager(shortname) manager.parentService = self #check and see if the model is bound if not AppManager(shortname).running: applog('Starting Application Manager') manager.start() except: failure = Failure() #bad plugin, not adaptable failures = (InvalidPlugin, TypeError) if failure.check(*failures) and manager: log('plugin for %s is invalid' % (manager.name, )) manager.action.__class__.delete(manager.action) try: pluginFactory.delete_plugin(manager.model) except: pass #silence AppManager.delete(manager) if not config.EXCESSIVE_LOGGING: continue #avoid extra logging try: failure.raiseException() except: crashReport('ApplicationLoader', self) Service.startService(self) Event('instance-started').subscribe(self.reset_tracking) #wire allapps action into the server drone.builtins.update({ 'allapps': self.allapps_action, 'applist': self.applist_action, }) #delay scanning by some interval config.reactor.callLater(SERVICECONFIG.initial_delay, self._start_all_tasks)
def _scan(self): for pid in listProcesses(): try: AppProcess(Server(config.HOSTNAME), pid) except InvalidProcess: pass except IOError: pass #happens on linux when a pid dies except: err('process table scanning error') #scan for crashed instances for app in App.objects: if not app.__class__.isValid(app): continue for ai in app.localappinstances: if not ai.__class__.isValid(ai): continue if ai in self.tracking: continue if not self.first_run: #avoid process table races self.tracking.add(ai) config.reactor.callLater(SERVICECONFIG.recovery_period, self.tracking.discard, ai) if not ai.enabled: continue #skip disabled result = None if ai.running and not ai.shouldBeRunning: ai.shouldBeRunning = True if ai.running: continue manager = AppManager(ai.app.name) if not manager.running: continue #skip managers that are not running if not manager.discover: continue #app manager claims to be ok #look for processes that we can assimilate d = manager.model.findProcesses() wfd = defer.waitForDeferred(d) yield wfd for (pid, result) in wfd.getResult(): d = manager.model.assimilateProcess(result) wfd2 = defer.waitForDeferred(d) yield wfd2 ai2 = wfd2.getResult() if ai2 and isinstance(ai2, AppInstance) and ai2 is ai: Event('instance-found').fire(instance=ai) manager.log('Sucessfully assimilated PID %d' % ai2.pid) if ai.running: continue #may have assimilated the app if not ai.crashed: continue if not ai.enabled: continue #disabled instances are not actionable if self.first_run: continue #avoid process table races Event('instance-crashed').fire(instance=ai) #cool off on eventing for a little while #keep the process objects up to date for process in AppProcess.objects: try: if not process.localInstall: continue if not process.running: AppProcess.delete(process) except: err('process book keeping error') d = defer.Deferred() config.reactor.callLater(0.01, d.callback, None) wfd = defer.waitForDeferred(d) yield wfd wfd.getResult() self.first_run = False yield 'done'