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)
Esempio n. 3
0
    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
Esempio n. 5
0
    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)
Esempio n. 6
0
    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)
Esempio n. 7
0
    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)
Esempio n. 8
0
    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