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()
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)
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
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']
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
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']
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()
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
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']
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
def test_import_object(): assert dt.timedelta == import_object('datetime.timedelta')
def test_import_object_fail_when_no_object(name): with pytest.raises(ValueError) as e: import_object(name) assert "Invalid name" in str(e)