Beispiel #1
0
    def __call__(self):
        config = self.context.config

        # Initialize logging
        self.context.config.configure_logging()

        # Call application init handler
        if config.init_handler:
            init_handler = import_object(config.init_handler)
            init_handler(self.context)
        # Register SIGUSR1 handler
        if config.sigusr1_handler:
            sigusr1_handler = import_object(config.sigusr1_handler)

            def sigusr1_signal_handler(dummy_signum, dummy_frame):
                """
                Handle SIGUSR2 signal. Call function which is defined
                in the **settings.SIGUSR2_HANDLER** setting and forward
                signal to all workers.
                """
                sigusr1_handler(self.context)
                if (self.pid == os.getpid() and
                        not self.service_processes_in_thread):
                    for worker in self.workers:
                        if worker.process:
                            os.kill(worker.process.pid, signal.SIGUSR1)
            signal.signal(signal.SIGUSR1, sigusr1_signal_handler)
        else:
            signal.signal(signal.SIGUSR1, signal.SIG_IGN)
        # Register SIGUSR2 handler
        if config.sigusr2_handler:
            sigusr2_handler = import_object(config.sigusr2_handler)

            def sigusr2_signal_handler(dummy_signum, dummy_frame):
                """
                Handle SIGUSR2 signal. Call function which is defined in
                the **settings.SIGUSR2_HANDLER** setting.
                """
                sigusr2_handler(self.context)
            signal.signal(signal.SIGUSR2, sigusr2_signal_handler)
        else:
            signal.signal(signal.SIGUSR2, signal.SIG_IGN)

        # Start service processes
        if self.service_processes_start:
            self.start_service_processes()
        # Run command
        self.command()
        # Stop service processes
        if not self.service_processes_in_thread:
            for worker in self.workers:
                worker.process.terminate()
        else:
            for worker in self.workers:
                worker.stop()
Beispiel #2
0
    def start_service_processes(self):
        """
        Run service processes defined in the **settings.SERVICE_PROCESSES**.
        According to :attribute:`service_processes_in_thread` attribute run
        service process either in thread, or as a new process.
        """
        settings = self.context.config.settings
        service_processes = getattr(settings, 'SERVICE_PROCESSES', ())
        separate_process = not self.service_processes_in_thread

        for process in service_processes:
            process_cls = import_object(process[0])
            process_name = process_cls.__name__
            wait_unless_ready, timeout = process[1], process[2]

            def worker_factory(args):
                """
                Return instance of the worker.
                """
                process_cls, context, separate_process = args
                return process_cls.get_instance(
                    context, separate_process=separate_process)

            self.logger.info("Init management command '%s'", process_name)

            worker = Worker(name=process_name,
                            factory=worker_factory,
                            args=(process_cls, self.context, separate_process))
            worker.start(wait_unless_ready=wait_unless_ready, timeout=timeout)

            self.workers.append(worker)
Beispiel #3
0
def get_tornado_apps(context, debug=False):
    """
    Create Tornado's application for all interfaces which are defined
    in the configuration. *context* is instance of the
    :class:`shelter.core.context.Context`. If *debug* is :const:`True`,
    server will be run in **DEBUG** mode. Return :class:`list` of the
    :class:`tornado.web.Application` instances.
    """
    if context.config.app_settings_handler:
        app_settings_handler = import_object(
            context.config.app_settings_handler)
        settings = app_settings_handler(context)
    else:
        settings = {}

    apps = []
    for interface in context.config.interfaces:
        urls = interface.urls
        if not urls:
            urls = [tornado.web.URLSpec('/', NullHandler)]
        apps.append(
            tornado.web.Application(urls,
                                    debug=debug,
                                    context=context,
                                    interface=interface,
                                    **settings))
    return apps
Beispiel #4
0
    def interfaces(self):
        """
        Interfaces as a :class:`list`of the
        :class:`shelter.core.config.Config.Interface` instances.
        """
        if 'interfaces' not in self._cached_values:
            self._cached_values['interfaces'] = []
            for name, interface in six.iteritems(self.settings.INTERFACES):
                interface_name = 'interface_%s' % name
                # Hostname + port
                try:
                    host, port = parse_host(
                        self.config_parser.get(interface_name, 'Listen'))
                except CONFIGPARSER_EXC:
                    host, port = parse_host(interface['LISTEN'])
                # Processes
                try:
                    processes = self.config_parser.getint(
                        interface_name, 'Processes')
                except CONFIGPARSER_EXC:
                    processes = int(interface.get('PROCESSES', 1))
                # Urls
                try:
                    urls_obj_name = self.config_parser.get(
                        interface_name, 'Urls')
                except CONFIGPARSER_EXC:
                    urls_obj_name = interface.get('URLS', '')
                if urls_obj_name:
                    urls = import_object(urls_obj_name)
                else:
                    urls = ()

                self._cached_values['interfaces'].append(
                    self.Interface(name, host, port, processes, urls))
        return self._cached_values['interfaces']
Beispiel #5
0
def get_config_class(settings):
    """
    According to **settings.CONFIG_CLASS** return either config class
    defined by user or default :class:`shelter.core.config.Config`.
    """
    config_cls_name = getattr(settings, 'CONFIG_CLASS', '')
    if config_cls_name:
        config_cls = import_object(config_cls_name)
    else:
        config_cls = Config
    return config_cls
Beispiel #6
0
 def context_class(self):
     """
     Context as a :class:`shelter.core.context.Context` class or subclass.
     """
     if 'context_class' not in self._cached_values:
         context_cls_name = getattr(self.settings, 'CONTEXT_CLASS', '')
         if context_cls_name:
             context_class = import_object(context_cls_name)
         else:
             context_class = Context
         self._cached_values['context_class'] = context_class
     return self._cached_values['context_class']
Beispiel #7
0
    def __call__(self):
        # Initialize logging
        self._configure_logging()

        # Call application init handler(s)
        init_handler_setting = self.context.config.init_handler
        if init_handler_setting:
            if isinstance(init_handler_setting, str):
                init_handlers = [init_handler_setting]
            else:
                init_handlers = init_handler_setting
            for init_handler in init_handlers:
                self.logger.info("Run init handler '%s'", init_handler)
                init_handler_obj = import_object(init_handler)
                init_handler_obj(self.context)

        # Register SIGUSR1 handler
        handler_name = self.context.config.sigusr1_handler
        if handler_name:
            self.logger.info("Register SIGUSR1 handler '%s'", handler_name)
            self._sigusr1_handler_func = import_object(handler_name)
            signal.signal(signal.SIGUSR1, self.sigusr1_handler)
        else:
            signal.signal(signal.SIGUSR1, signal.SIG_IGN)
        # Register SIGUSR2 handler
        handler_name = self.context.config.sigusr2_handler
        if handler_name:
            self.logger.info("Register SIGUSR2 handler '%s'", handler_name)
            self._sigusr2_handler_func = import_object(handler_name)
            signal.signal(signal.SIGUSR2, self.sigusr2_handler)
        else:
            signal.signal(signal.SIGUSR2, signal.SIG_IGN)

        # Call initialization method
        self.initialize()

        # Run command
        self.command()
Beispiel #8
0
def get_management_commands(settings):
    """
    Find registered managemend commands and return their classes
    as a :class:`dict`. Keys are names of the management command
    and values are classes of the management command.
    """
    app_commands = getattr(settings, 'MANAGEMENT_COMMANDS', ())
    commands = {}
    for name in itertools.chain(SHELTER_MANAGEMENT_COMMANDS, app_commands):
        command_obj = import_object(name)
        if not issubclass(command_obj, BaseCommand):
            raise ValueError("'%s' is not subclass of the BaseCommand" % name)
        commands[command_obj.name] = command_obj
    return commands
Beispiel #9
0
 def interfaces(self):
     """
     Interfaces as a :class:`list`of the
     :class:`shelter.core.config.Config.Interface` instances.
     """
     if 'interfaces' not in self._cached_values:
         self._cached_values['interfaces'] = []
         for name, interface in six.iteritems(self.settings.INTERFACES):
             host, port = parse_host(interface['LISTEN'])
             processes = int(interface.get('PROCESSES', 1))
             urls_obj_name = interface.get('URLS', '')
             if urls_obj_name:
                 urls = import_object(urls_obj_name)
             else:
                 urls = ()
             self._cached_values['interfaces'].append(
                 self.Interface(name, host, port, processes, urls))
     return self._cached_values['interfaces']
Beispiel #10
0
    def init_service_processes(self):
        """
        Prepare processes defined in the **settings.SERVICE_PROCESSES**.
        Return :class:`list` of the :class:`ProcessWrapper` instances.
        """
        processes = []

        for process_struct in getattr(self.context.config.settings,
                                      'SERVICE_PROCESSES', ()):
            process_cls = import_object(process_struct[0])
            wait_unless_ready, timeout = process_struct[1], process_struct[2]

            self.logger.info("Init service process '%s'", process_cls.__name__)

            processes.append(
                ProcessWrapper(process_cls, (self.context, ),
                               wait_unless_ready=wait_unless_ready,
                               timeout=timeout))

        return processes
Beispiel #11
0
def test_import_object():
    assert dt.timedelta == import_object('datetime.timedelta')
Beispiel #12
0
def test_import_object_fail_when_no_object(name):
    with pytest.raises(ValueError) as e:
        import_object(name)
    assert "Invalid name" in str(e)