Ejemplo n.º 1
0
    def run(self):
        """ Run the Daemon. Setup signal handler, task registry, scheduler,
        listener and executors. Runs the main control loop.
        """
        try:
            # setup signal handlers for shutdown or immediate termination
            signal(SIGINT, self.shutdown)
            signal(SIGTERM, self.terminate)

            registry.initialize()

            # create executors, listener and scheduler
            self.executor_pool = ThreadPool(1)
            self.scheduler = Scheduler(self.on_scheduled)
            self.listener = get_listener()

            self.scheduler.start()
            self.reload_schedule()

            while True:
                try:
                    conn = self.listener.accept()
                except socket.error as exc:
                    # connection closed
                    if exc.errno in (errno.EINTR, errno.EBADF):
                        logger.info(
                            "Listener interrupted. Exiting main control loop."
                        )
                        break
                    else:
                        raise

                command = None
                try:
                    logger.debug("Client connected: %s", conn)
                    message = conn.recv()
                    logger.debug("Received message: %r", message)

                    command = message[0]
                    params = message[1:]

                    if command == "reload":
                        self.reload_schedule()

                    elif command == "restart":
                        job = models.Job.objects.get(id=params[0])
                        logger.info("Restarting job '%s'" % job)
                        self.executor_pool.apply_async(
                            registry.run, [job], job.arguments
                        )
                    elif command == "abort":
                        pass
                        # TODO: implement
                except Exception as exc:
                    logger.exception("Daemon command %s failed." % command)

        finally:
            self.shutdown()
Ejemplo n.º 2
0
class Daemon(object):
    """ Multi-purpose task management daemon.
    """
    def __init__(self):
        self.scheduler = None
        self.listener = None
        self.executor_pool = None

    def run(self):
        """ Run the Daemon. Setup signal handler, task registry, scheduler,
        listener and executors. Runs the main control loop.
        """
        try:
            # setup signal handlers for shutdown or immediate termination
            signal(SIGINT, self.shutdown)
            signal(SIGTERM, self.terminate)

            registry.initialize()

            # create executors, listener and scheduler
            self.executor_pool = ThreadPool(1)
            self.scheduler = Scheduler(self.on_scheduled)
            self.listener = get_listener()

            self.scheduler.start()
            self.reload_schedule()

            while True:
                try:
                    conn = self.listener.accept()
                except socket.error as exc:
                    # connection closed
                    if exc.errno in (errno.EINTR, errno.EBADF):
                        logger.info(
                            "Listener interrupted. Exiting main control loop."
                        )
                        break
                    else:
                        raise

                command = None
                try:
                    logger.debug("Client connected: %s", conn)
                    message = conn.recv()
                    logger.debug("Received message: %r", message)

                    command = message[0]
                    params = message[1:]

                    if command == "reload":
                        self.reload_schedule()

                    elif command == "restart":
                        job = models.Job.objects.get(id=params[0])
                        logger.info("Restarting job '%s'" % job)
                        self.executor_pool.apply_async(
                            registry.run, [job], job.arguments
                        )
                    elif command == "abort":
                        pass
                        # TODO: implement
                except Exception as exc:
                    logger.exception("Daemon command %s failed." % command)

        finally:
            self.shutdown()

    def shutdown(self, signum=None, frame=None, terminate=False):
        """ Shutdown method. When ``terminate`` is ``True``, then the underlying
        pool is terminated. Otherwise, running tasks are finished.
        """
        if self.executor_pool:
            if terminate:
                self.executor_pool.terminate()
            else:
                self.executor_pool.close()

        if self.scheduler:
            self.scheduler.shutdown()
            self.scheduler = None
        if self.listener:
            self.listener.close()
            self.listener = None

    def terminate(self, signum=None, frame=None):
        self.shutdown(terminate=True)

    def on_scheduled(self, scheduled_task):
        task = scheduled_task.task
        arguments = scheduled_task.argument_values
        scheduled_task.delete()

        print task, arguments
        self.executor_pool.apply_async(run_task, [task], arguments)

    def reload_schedule(self):
        """ Reload the scheduled items from the database.
        """
        self.scheduler.reset()
        for scheduled_task in models.ScheduledJob.objects.all():
            self.scheduler.schedule(scheduled_task.when, [scheduled_task])