def register_log_manager(self, log_manager: LogManagerService) -> None: """ Registers the log manager to be used with the application. """ # The instance() method of Singleton is not recognized by pylint. # pylint: disable=no-member ServiceLocator.instance().register_provider(LogManagerService, log_manager)
def __init__( self, service_directory: str, service_package: str, config_directory: str, business_logic: BusinessLogic, debug_mode: bool = False, ) -> None: """ Creates a new Application instance. Args: service_directory: The directory which contains the initial services. service_package: The name of the package containing the services. config_directory: The directory which contains the initial application configuration. business_logic: The business logic representation. debug_mode: Whether or not the application should be started in debug mode. """ # Pylint doesn't recognize the instance() method of Singleton. #pylint: disable=no-member self._business_logic = business_logic """ The actual business logic implementation of the application. """ self._debug_mode = debug_mode """ Whether or not the application should be started in debug mode. """ # Create the logging configuration self._business_logic.initialize_logging() log_manager = ServiceLocator.instance().get_provider(LogManagerService) if log_manager is not None: log_manager.initialize(config_directory, self._debug_mode) # Register the initial services directory with the service locator ServiceLocator.instance().register_path(service_directory, service_package) # Initialize the configuration handler with the config directory configuration = ServiceLocator.instance().get_provider( ConfigurationService) if configuration is not None: configuration.initialize(config_directory)
def test_accessing_services(self): """ Tests that services can be accessed throug the ServiceLocator. """ ServiceLocator.instance().register_path(SERVICE_DIR, 'services') ServiceLocator.instance().discover_services() from services.testservice import AbstractService provider = ServiceLocator.instance().get_provider(AbstractService) self.assertNotEqual(provider, None) self.assertTrue(provider.service_function())
def execute(self) -> int: """ Contains the main execution logic of the application. """ # Pylint doesn't recognize the instance() method of Singleton. #pylint: disable=no-member # Load the configuration configuration = ServiceLocator.instance().get_provider( ConfigurationService) if configuration is not None: configuration.load() # Catching every uncaught exception here is intentional so that # the applications can react to it and to also set the proper # exit code of the application. #pylint: disable=broad-except try: result = self._business_logic.main_loop() except Exception as error: self._business_logic.on_uncaught_exception(error) result = ApplicationReturnCodes.UNCAUGHT_EXCEPTION return result
def execute(self) -> None: """ Executes the task. """ from suisei.murasame.processing import TaskExecutor if self._type == TaskTypes.RECURRING \ and self._expected_execution is not None: # It is a recurring task that has been executed before current_time = datetime.datetime.utcnow() if current_time >= self._expected_execution: self._logic(self._data) self._update_expected_execution(current_time) # Pylint doesn't recognize the instance() method of Singleton. #pylint: disable=no-member executor = ServiceLocator.instance().get_provider(TaskExecutor) if executor is not None: executor.schedule(self) else: # Just a normal task or the first execution of a recurring task self._logic(self._data) # If it was the first execution of a recurringtask, add the task # back to the queue. if self._type == TaskTypes.RECURRING: self._update_expected_execution(datetime.datetime.utcnow()) # Pylint doesn't recognize the instance() method of Singleton. #pylint: disable=no-member executor = ServiceLocator.instance().get_provider(TaskExecutor) if executor is not None: executor.schedule(self)
def test_duplicate_service_path_registration(self): """ Tests that service paths cannot be registered twice. """ ServiceLocator.instance().register_path(SERVICE_DIR, 'services') ServiceLocator.instance().register_path(SERVICE_DIR, 'services') ServiceLocator.instance().discover_services() from services.testservice import AbstractService self.assertNotEqual( ServiceLocator.instance().get_provider(AbstractService), None)
def test_service_discovery(self): """ Tests that service discovery works properly. """ # STEP #1 - Load a valid service path # Register the path with the service locator ServiceLocator.instance().register_path(SERVICE_DIR, 'services') # Run service discovery ServiceLocator.instance().discover_services() from services.testservice import AbstractService self.assertNotEqual( ServiceLocator.instance().get_provider(AbstractService), None) # STEP #2 - Try to load an invalid service path ServiceLocator.instance().register_path('/invalid/path', 'services') ServiceLocator.instance().discover_services() self.assertNotEqual( ServiceLocator.instance().get_provider(AbstractService), None)
def _create_workers(self) -> None: """ Creates the worker threads to be used for task execution. """ # The instance() method of the singleton is not recognized by pylint. # pylint: disable=no-member configuration = \ ServiceLocator.instance().get_provider(ConfigurationService) num_workers = 4 if configuration is not None: num_workers = configuration.get( 'suisei.murasame.processing.numworkers') # Create the required amount of worker threads. Worker #0 will be the # IO thread. for i in range(0, num_workers - 1): handle_io = False handle_normal = True handle_high = True if i == 0: handle_io = True handle_normal = False handle_high = False worker_name = 'Murasame Worker #{}'.format(i) worker = Worker(thread_id=i, thread_name=worker_name, executor=self, handle_high_prio=handle_high, handle_normal_prio=handle_normal, handle_io=handle_io) # Make the worker thread a daemon thread to avoid hanging at exit # when something in the main thread breaks and proper shutdown # cannot be initiated worker.daemon = True self._workers.append(worker)
def main_loop(self) -> int: """ The main loop of the supervisor daemon. """ while True: try: # The instance() method of Singleton is not detected by pylint # pylint: disable=no-member executor = ServiceLocator.instance().get_provider(TaskExecutor) if executor: executor.update() logger = logging.getLogger('suisei.tenshi.supervisor') logger.debug('Tick...') time.sleep(1) except KeyboardInterrupt: raise SystemExit