예제 #1
0
    def __init__(self, config, service_id, worker_id, parent_pipe,
                 started_hooks, graceful_shutdown_timeout):
        super(ServiceWorker, self).__init__()
        self._ready = threading.Event()
        if parent_pipe is not None:
            _utils.spawn(self._watch_parent_process, parent_pipe)

        # Reseed random number generator
        random.seed()

        args = tuple() if config.args is None else config.args
        kwargs = dict() if config.kwargs is None else config.kwargs
        self.service = config.service(worker_id, *args, **kwargs)
        self.service._initialize(worker_id)
        if self.service.graceful_shutdown_timeout is None:
            self.service.graceful_shutdown_timeout = graceful_shutdown_timeout

        self.title = "%(name)s(%(worker_id)d) [%(pid)d]" % dict(
            name=self.service.name, worker_id=worker_id, pid=os.getpid())

        # Set process title
        _utils.setproctitle("%(pname)s: %(name)s worker(%(worker_id)d)" %
                            dict(pname=_utils.get_process_name(),
                                 name=self.service.name,
                                 worker_id=worker_id))

        # We are ready tell them
        self._ready.set()
        _utils.run_hooks('new_worker', started_hooks, service_id, worker_id,
                         self.service)
예제 #2
0
    def __init__(self, config, service_id, worker_id, parent_pipe,
                 started_hooks, graceful_shutdown_timeout):
        super(ServiceWorker, self).__init__()
        self._ready = threading.Event()
        _utils.spawn(self._watch_parent_process, parent_pipe)

        # Reseed random number generator
        random.seed()

        args = tuple() if config.args is None else config.args
        kwargs = dict() if config.kwargs is None else config.kwargs
        self.service = config.service(worker_id, *args, **kwargs)
        self.service._initialize(worker_id)
        if self.service.graceful_shutdown_timeout is None:
            self.service.graceful_shutdown_timeout = graceful_shutdown_timeout

        self.title = "%(name)s(%(worker_id)d) [%(pid)d]" % dict(
            name=self.service.name, worker_id=worker_id, pid=os.getpid())

        # Set process title
        _utils.setproctitle(
            "%(pname)s: %(name)s worker(%(worker_id)d)" % dict(
                pname=_utils.get_process_name(), name=self.service.name,
                worker_id=worker_id))

        # We are ready tell them
        self._ready.set()
        _utils.run_hooks('new_worker', started_hooks, service_id, worker_id,
                         self.service)
예제 #3
0
    def _start_worker(self, service_id, worker_id):
        self._slowdown_respawn_if_needed()

        pid = os.fork()
        if pid != 0:
            self._running_services[service_id][pid] = worker_id
            return

        # reset parent signals
        signal.signal(signal.SIGINT, signal.SIG_DFL)
        signal.signal(signal.SIGALRM, signal.SIG_DFL)
        signal.signal(signal.SIGTERM, signal.SIG_DFL)
        signal.signal(signal.SIGHUP, signal.SIG_DFL)

        # Close write to ensure only parent has it open
        os.close(self.writepipe)
        os.close(self.signal_pipe_r)
        os.close(self.signal_pipe_w)

        _utils.spawn(self._watch_parent_process)

        # Reseed random number generator
        random.seed()

        # Create and run a new service
        with _utils.exit_on_exception():
            self._current_process = _service.ServiceWorker(
                self._services[service_id], worker_id,
                self._graceful_shutdown_timeout)
            self._run_hooks('new_worker', service_id, worker_id,
                            self._current_process.service)
            self._current_process.wait_forever()
예제 #4
0
def window_sanity_check():
    p = cotyledon.ServiceManager()
    p.add(LigthService)
    t = _utils.spawn(p.run)
    time.sleep(10)
    os.kill(os.getpid(), signal.SIGTERM)
    t.join()
예제 #5
0
    def run(self, wait_interval=0.01, graceful_shutdown_timeout=60):
        """Start and supervise services workers

        This method will start and supervise all children processes
        until the master process asked to shutdown by a SIGTERM.

        All spawned processes are part of the same unix process group.
        """

        self._running_services = collections.defaultdict(dict)
        self._forktimes = []
        self._graceful_shutdown_timeout = graceful_shutdown_timeout
        self._wait_interval = wait_interval

        self._dead = threading.Event()
        # NOTE(sileht): Set it on startup, so first iteration
        # will spawn initial workers
        self._got_sig_chld = threading.Event()
        self._got_sig_chld.set()

        self._child_supervisor = None

        self._hooks = {
            'terminate': [],
            'reload': [],
            'new_worker': [],
        }

        self._death_detection_pipe = multiprocessing.Pipe(duplex=False)

        self._systemd_notify_once()
        self._child_supervisor = _utils.spawn(self._child_supervisor_thread)
        self._wait_forever()
예제 #6
0
def window_sanity_check():
    p = cotyledon.ServiceManager()
    p.add(LigthService)
    t = _utils.spawn(p.run)
    time.sleep(10)
    os.kill(os.getpid(), signal.SIGTERM)
    t.join()
예제 #7
0
    def _on_signal_received(self, sig):
        # Code below must not block to return to select.select() and catch
        # next signals
        if sig == _utils.SIGALRM:
            self._alarm()
        elif sig == signal.SIGTERM:
            LOG.info('Caught SIGTERM signal, '
                     'graceful exiting of service %s' % self.title)

            if self.service.graceful_shutdown_timeout > 0:
                if os.name == "posix":
                    signal.alarm(self.service.graceful_shutdown_timeout)
                else:
                    threading.Timer(self.service.graceful_shutdown_timeout,
                                    self._alarm).start()
            _utils.spawn(self.service._terminate)
        elif sig == _utils.SIGHUP:
            _utils.spawn(self.service._reload)
예제 #8
0
    def _on_signal_received(self, sig):
        # Code below must not block to return to select.select() and catch
        # next signals
        if sig == _utils.SIGALRM:
            self._alarm()
        elif sig == signal.SIGTERM:
            LOG.info('Caught SIGTERM signal, '
                     'graceful exiting of service %s' % self.title)

            if self.service.graceful_shutdown_timeout > 0:
                if os.name == "posix":
                    signal.alarm(self.service.graceful_shutdown_timeout)
                else:
                    threading.Timer(self.service.graceful_shutdown_timeout,
                                    self._alarm).start()
            _utils.spawn(self.service._terminate)
        elif sig == _utils.SIGHUP:
            _utils.spawn(self.service._reload)
예제 #9
0
    def _on_signal_received(self, sig):
        # Code below must not block to return to select.select() and catch
        # next signals
        if sig == signal.SIGALRM:
            LOG.info('Graceful shutdown timeout (%d) exceeded, '
                     'exiting %s now.' %
                     (self.service.graceful_shutdown_timeout,
                      self.title))
            os._exit(1)

        elif sig == signal.SIGTERM:
            LOG.info('Caught SIGTERM signal, '
                     'graceful exiting of service %s' % self.title)

            if self.service.graceful_shutdown_timeout > 0:
                signal.alarm(self.service.graceful_shutdown_timeout)
            _utils.spawn(self.service._terminate)
        elif sig == signal.SIGHUP:
            _utils.spawn(self.service._reload)
예제 #10
0
    def run(self):
        """Start and supervise services workers

        This method will start and supervise all children processes
        until the master process asked to shutdown by a SIGTERM.

        All spawned processes are part of the same unix process group.
        """

        self._systemd_notify_once()
        self._child_supervisor = _utils.spawn(self._child_supervisor_thread)
        self._wait_forever()
예제 #11
0
 def wait_forever(self):
     LOG.debug("Run service %s" % self.title)
     _utils.spawn(self.service._run)
     super(ServiceWorker, self)._wait_forever()
예제 #12
0
 def wait_forever(self):
     LOG.debug("Run service %s" % self.title)
     _utils.spawn(self.service._run)
     super(ServiceWorker, self)._wait_forever()