Exemple #1
0
 def stop(self):
     pid = pidlockfile.read_pid_from_pidfile(settings.PIDFILE)
     if pid is None:
         sys.stderr.write('Failed to read PID from pidfile "%(pidfile)s".\n' % {
             'pidfile': settings.PIDFILE,
         })
         sys.exit(1)
     elif not self._is_pid_running(pid):
         sys.stderr.write('PID %(pid)s in pidfile "%(pidfile)s" is not running.\n' % {
             'pid': pid,
             'pidfile': settings.PIDFILE,
         })
         sys.exit(7)
     else:
         try:
             os.kill(pid, signal.SIGTERM)
             sys.stdout.write('Stopping')
             while self._is_pid_running(pid):
                 sys.stdout.write('.')
                 sys.stdout.flush()
                 time.sleep(1)
             sys.stdout.write(' Ok!\n')
             pidlockfile.remove_existing_pidfile(settings.PIDFILE)
             sys.exit(0)
         except OSError as e:
             sys.stderr.write('Failed to terminate PID %(pid)s: %(message)s.\n' % {
                 'pid': pid,
                 'message': e,
             })
             sys.exit(1)
 def test_removes_specified_filename(self):
     """ Should attempt to remove specified PID file filename. """
     pidfile_path = self.scenario['path']
     expect_mock_output = """\
         Called os.remove(%(pidfile_path)r)
         """ % vars()
     pidlockfile.remove_existing_pidfile(pidfile_path)
     scaffold.mock_restore()
     self.failUnlessMockCheckerMatch(expect_mock_output)
 def test_ignores_file_not_exist_error(self):
     """ Should ignore error if file does not exist. """
     pidfile_path = self.scenario['path']
     mock_error = OSError(errno.ENOENT, "Not there", pidfile_path)
     os.remove.mock_raises = mock_error
     expect_mock_output = """\
         Called os.remove(%(pidfile_path)r)
         """ % vars()
     pidlockfile.remove_existing_pidfile(pidfile_path)
     scaffold.mock_restore()
     self.failUnlessMockCheckerMatch(expect_mock_output)
def stop_worker(args):
    """Sends SIGTERM to Celery worker"""
    # Read PID from file
    pid_file_path, _, _, _ = setup_locations(process=WORKER_PROCESS_NAME)
    pid = read_pid_from_pidfile(pid_file_path)

    # Send SIGTERM
    if pid:
        worker_process = psutil.Process(pid)
        worker_process.terminate()

    # Remove pid file
    remove_existing_pidfile(pid_file_path)
Exemple #5
0
    def start(self, detach=True, debug=False):
        # Check if the service is already running.
        pid = pidlockfile.read_pid_from_pidfile(settings.PIDFILE)
        if pid is not None and self._is_pid_running(pid):
            sys.stderr.write('PID %(pid)s in pidfile "%(pidfile)s" is already running.\n' % {
                'pid': pid,
                'pidfile': settings.PIDFILE,
            })
            sys.exit(1)

        # Remove pidfile (may not exists).
        pidlockfile.remove_existing_pidfile(settings.PIDFILE)

        # Adjust daemon context.
        if not detach:
            self.detach_process = False
            self.stdout = sys.stdout
            self.stderr = sys.stderr

        # Enter daemon context.
        with self:
            # Initializations.
            pid = os.getpid()
            self._shutdown_event = multiprocessing.Event()
            self._logging_queue = multiprocessing.Queue(-1)
            self._init_logger(debug=debug, console=not detach)

            # Log.
            logging.getLogger('varnishsentry').info(
                'Starting varnishsentry service (PID %d)', pid)

            # Launch consumers.
            for id, config in settings.WORKERS.iteritems():
                worker = Consumer(
                    pid,
                    self._shutdown_event,
                    self._logging_queue,
                    id,
                    config,
                    debug)
                self._workers.append(worker)
                worker.start()

            # Periodically check for termination and for terminated workers.
            while not self._sigterm:
                try:
                    # Wait for incoming messages (up to 1 second).
                    record = self._logging_queue.get(True, 1)

                    # Process incoming message.
                    if record is not None:
                        logging.getLogger(record.name).handle(record)
                except:
                    pass

                # Some worker has terminated? => rebuild the list of workers.
                if self._sigchld > 0:
                    workers = []
                    for worker in self._workers:
                        if worker.is_alive():
                            workers.append(worker)
                        else:
                            worker.terminate()
                            logging.getLogger('varnishsentry').error(
                                'Worker %s terminated unexpectedly with status '
                                'code %d', worker.name, worker.exitcode)
                            workers.append(worker.restart())
                    self._workers = workers
                    self._sigchld -= 1

            # Set shutdown event and wait a few seconds for a graceful shutdown
            # of all workers.
            self._shutdown_event.set()
            retries = 5
            while retries > 0:
                if any([worker.is_alive() for worker in self._workers]):
                    retries = retries - 1
                    time.sleep(1)
                else:
                    break

            # After timeout, force shutdown of any alive worker.
            for worker in self._workers:
                if worker.is_alive():
                    worker.terminate()

            # Wait for all workers termination.
            for worker in self._workers:
                worker.join()

        # Clean up and exit.
        pidlockfile.remove_existing_pidfile(settings.PIDFILE)
        logging.getLogger('varnishsentry').info(
            'Shutting down varnishsentry service (PID %d)', pid)
        sys.exit(0)