def testB(self): """ Check we can terminate before pausing workers """ compDummy = Dummy() print('create manager') manager = WorkerThreadManager(compDummy) print('add worker') manager.addWorker(DummyWorker2(), 1) print('terminate worker') manager.terminateWorkers()
def startComponent(self): """ _startComponent_ Start up the component """ # Registration in oldMsgService self.ms.registerAs("CrabJobCreatorComponent") self.ms.subscribeTo("JobFailed") self.ms.subscribeTo("JobSuccess") self.ms.subscribeTo("CrabJobCreatorComponent:EndDebug") # Registration in new MsgService self.myThread.transaction.begin() self.newMsgService.registerAs("CrabJobCreatorComponent") self.myThread.transaction.commit() self.ms.subscribeTo("CrabJobCreatorComponent:HeartBeat") self.ms.remove("CrabJobCreatorComponent:HeartBeat") self.ms.publish("CrabJobCreatorComponent:HeartBeat","",self.HeartBeatDelay) self.ms.commit() self.workerCfg = self.prepareBaseStatus() compWMObject = WMObject() manager = WorkerThreadManager(compWMObject) manager.addWorker(CrabJobCreatorPoller(self.workerCfg), float(self.timePoolDB)) ####################################### try: while True: try: event, payload = self.ms.get( wait = False ) if event is None: time.sleep( self.ms.pollTime ) continue else: self.__call__(event, payload) self.ms.commit() except Exception, exc: logging.error("ERROR: Problem managing message...") logging.error(str(exc)) except Exception, e: logging.error(e) logging.info(traceback.format_exc())
def testWorkerError(self): """If a worker raises an exception terminate the entire component""" compDummy = Dummy() print('create manager') manager = WorkerThreadManager(compDummy) # needed for handling errors - harness would generally set this myThread = threading.currentThread() myThread.workerThreadManager = manager print('add workers') manager.addWorker(DummyWorker1(), 0.1) manager.addWorker(ErrorWorker(), 0.1) print('run workers, one will throw an error') manager.resumeWorkers() # should do something smarter here # too short a time and threads havent exited yet time.sleep(6) # all threads should have ended after worker raised exception self.assertEqual(manager.activeThreadCount, 0)
def testA(self): """ Check worker methods get called. We sleep occasionally to ensure these asynchronous calls have enough time to be called """ # Create a worker manager compDummy = Dummy() print('create manager') manager = WorkerThreadManager(compDummy) # Pause it print('pause workers') manager.pauseWorkers() # Add a worker, and check init method gets called print('add worker') manager.addWorker(DummyWorker1(), 1) time.sleep(3) self.assertEqual(WorkerThreadsTest._setupCalled, True) # Ensure the algo wasn't called whilst paused self.assertEqual(WorkerThreadsTest._algoCalled, False) print('resume workers') # Run the workers, pause, and check algo method gets called manager.resumeWorkers() time.sleep(3) manager.pauseWorkers() self.assertEqual(WorkerThreadsTest._algoCalled, True) print('terminate workers') # Terminate the workers, and check terminate method gets called manager.terminateWorkers() time.sleep(3) self.assertEqual(WorkerThreadsTest._terminateCalled, True)
def initInThread(self): """ Default intialization of the harness including setting some diagnostic messages. This method is called when we call 'prepareToStart' """ try: self.messages = {} compName = self.config.Agent.componentName compSect = getattr(self.config, compName, None) if not hasattr(compSect, "logFile"): if not getattr(compSect, 'componentDir', None): errorMessage = "No componentDir for log entries found!\n" errorMessage += "Harness cannot run without componentDir.\n" logging.error(errorMessage) raise HarnessException(errorMessage) compSect.logFile = os.path.join(compSect.componentDir, "ComponentLog") print('Log file is: ' + compSect.logFile) logHandler = RotatingFileHandler(compSect.logFile, "a", 1000000000, 3) logMsgFormat = getattr( compSect, "logMsgFormat", "%(asctime)s:%(thread)d:%(levelname)s:%(module)s:%(message)s") logFormatter = \ logging.Formatter(logMsgFormat) logHandler.setFormatter(logFormatter) logLevelName = getattr(compSect, 'logLevel', 'INFO') logLevel = getattr(logging, logLevelName) logging.getLogger().addHandler(logHandler) logging.getLogger().setLevel(logLevel) self.logMsg = { 'DEBUG': logging.DEBUG, 'ERROR': logging.ERROR, 'NOTSET': logging.NOTSET, 'CRITICAL': logging.CRITICAL, 'WARNING': logging.WARNING, 'INFO': logging.INFO, 'SQLDEBUG': logging.SQLDEBUG } if hasattr(compSect, "logLevel") and compSect.logLevel in self.logMsg: logging.getLogger().setLevel(self.logMsg[compSect.logLevel]) WMLogging.sqldebug("wmcore level debug:") # If not previously set, force wmcore cache to current path if not os.environ.get('WMCORE_CACHE_DIR'): os.environ['WMCORE_CACHE_DIR'] = os.path.join( compSect.componentDir, '.wmcore_cache') logging.info(">>>Starting: " + compName + '<<<') # check which backend to use: MySQL, Oracle, etc... for core # services. # we recognize there can be more than one database. # be we offer a default database that is used for core services. logging.info(">>>Initializing default database") logging.info(">>>Check if connection is through socket") myThread = threading.currentThread() myThread.logger = logging.getLogger() logging.info(">>>Setting config for thread: ") myThread.config = self.config logging.info(">>>Building database connection string") # check if there is a premade string if not build it yourself. dbConfig = ConfigDBMap(self.config) dbStr = dbConfig.getDBUrl() options = dbConfig.getOption() # we only want one DBFactory per database so we will need to # to pass this on in case we are using threads. myThread.dbFactory = DBFactory(myThread.logger, dbStr, options) myThread.sql_transaction = True if myThread.dbFactory.engine: myThread.dbi = myThread.dbFactory.connect() myThread.transaction = Transaction(myThread.dbi) else: myThread.dbi = myThread.config.CoreDatabase.connectUrl myThread.sql_transaction = False # Attach a worker manager object to the main thread if not hasattr(myThread, 'workerThreadManager'): myThread.workerThreadManager = WorkerThreadManager(self) else: myThread.workerThreadManager.terminateSlaves.clear() myThread.workerThreadManager.pauseWorkers() logging.info(">>>Initialize transaction dictionary") (connectDialect, dummy) = dbStr.split(":", 1) if connectDialect.lower() == 'mysql': myThread.dialect = 'MySQL' elif connectDialect.lower() == 'oracle': myThread.dialect = 'Oracle' logging.info("Harness part constructor finished") except Exception as ex: logging.critical("Problem instantiating " + str(ex)) logging.error("Traceback: %s", str(traceback.format_exc())) raise
def testA(self): """ Check worker methods get called. We sleep occasionally to ensure these asynchronous calls have enough time to be called """ # Create a worker manager compDummy = Dummy() print('create manager') manager = WorkerThreadManager(compDummy) # Pause it print('pause workers') manager.pauseWorkers() # Add a worker, and check init method gets called print('add worker') manager.addWorker(DummyWorker1(), 1) time.sleep(3) self.assertEqual( WorkerThreadsTest._setupCalled , True ) # Ensure the algo wasn't called whilst paused self.assertEqual( WorkerThreadsTest._algoCalled , False ) print('resume workers') # Run the workers, pause, and check algo method gets called manager.resumeWorkers() time.sleep(3) manager.pauseWorkers() self.assertEqual( WorkerThreadsTest._algoCalled , True ) print('terminate workers') # Terminate the workers, and check terminate method gets called manager.terminateWorkers() time.sleep(3) self.assertEqual( WorkerThreadsTest._terminateCalled , True )