Exemple #1
0
 def reload(self):
     try:
         new_config = Config(self.filename)
     except Exception:
         LOG.exception("Error loading new config")
         return
     self.config = new_config
     self.stop_services(self.streams)
     self.stop_services(self.status_monitors)
     self.start_streams()
Exemple #2
0
 def reload(self):
     """Wait for reload events and reload config when event set."""
     while 1:
         try:
             yield from self.reload_event.wait()
             self.log.info("Reloading configuration...")
         except asyncio.CancelledError:
             return
         finally:
             self.reload_event.clear()
         try:
             config = Config(self, self.filename, self.verbose)
             self.log.debug("New config instance %s" % config)
             yield from config.validate()
             self.config = config
             self.log.info("Done")
         except asyncio.CancelledError:
             return
         except Exception:
             self.log.exception("Error loading new config")
Exemple #3
0
class Root:
    def __init__(self, loop, filename, verbose):
        self._running_objects = {}
        self._running_coros = set()
        self._running_cleanups = set()

        self.filename = filename
        self.verbose = verbose

        self.tasks = {}
        self.task_set = set()
        self.loop = loop
        self.providers = {}
        self.task_start_handlers = []
        self.task_end_handlers = []
        self.job_end_handlers = []
        self.job_update_handlers = []
        self.stop_event = asyncio.Event(loop=loop)
        self.reload_event = asyncio.Event(loop=loop)

        loop.add_signal_handler(signal.SIGINT, self.stop)
        loop.add_signal_handler(signal.SIGHUP, self.reload_event.set)

    def stop(self):
        self.loop.remove_signal_handler(signal.SIGINT)
        self.loop.remove_signal_handler(signal.SIGHUP)
        self.stop_event.set()

    @asyncio.coroutine
    def run_obj(self, obj):
        try:
            yield from self.run_coro(obj.run())
        except Exception:
            self.log.exception("Error running %s" % obj)

    @asyncio.coroutine
    def run_coro(self, coro):
        try:
            yield from coro
        except asyncio.CancelledError:
            self.log.info("Cancelled %s" % coro)
        except Exception:
            self.log.exception("Exception running %s" % coro)

    def start_task(self, task):
        """
        :param Task task:
        """
        if task.event.key in self.task_set:
            self.log.warning("Task '%s' is already running" % task.event.key)
            return
        self.task_set.add(task.event.key)
        fut = self.start_obj(task)
        self.tasks[fut] = task
        fut.add_done_callback(self.task_done_cb)

    def task_done_cb(self, fut):
        try:
            task = self.tasks.pop(fut)
            self.log.info("Finished task %s" % task)
            self.task_set.remove(task.event.key)
            for handler in self.task_end_handlers:
                try:
                    handler(task)
                except Exception:
                    self.log.exception(("Exception in task end "
                                        "handler %s %s") % (task, handler))
        except Exception:
            self.log.exception("Error in task_done_cb")

    def start_coro(self, coro):
        fut = asyncio.async(self.run_coro(coro), loop=self.loop)
        self._running_coros.add(fut)
        fut.add_done_callback(self._running_coros.remove)
        return fut

    def start_obj(self, obj):
        fut = asyncio.async(self.run_obj(obj), loop=self.loop)
        self._running_objects[fut] = obj
        if hasattr(obj, "cleanup"):
            fut.add_done_callback(self.schedule_cleanup)
        else:
            fut.add_done_callback(self._running_objects.pop)
        return fut

    @asyncio.coroutine
    def run_cleanup(self, obj):
        try:
            yield from obj.cleanup()
        except Exception:
            self.log.exception("Exception in cleanup %s" % obj)

    def schedule_cleanup(self, fut):
        obj = self._running_objects.pop(fut)
        fut = asyncio.async(self.run_cleanup(obj), loop=self.loop)
        self._running_cleanups.add(fut)
        fut.add_done_callback(self._running_cleanups.remove)

    def start_services(self):
        for service in self.config.iter_instances("service", "Service"):
            self.start_obj(service)

    def _load_config(self):
        self.config = Config(self, self.filename, self.verbose)
        self.config.configure_logging()
        self.log = logging.getLogger(__name__)

    @asyncio.coroutine
    def wait_fs(self, fs):
        """Wait for futures.

        :param fs: dict where key is future and value is related object
        """
        self.log.debug("Waiting for %s" % fs.values())
        while fs:
            done, pending = yield from asyncio.wait(
                    list(fs.keys()), return_when=futures.FIRST_COMPLETED)
            for fut in done:
                if fut in fs:
                    del(fs[fut])
            self.log.debug("Pending %s" % pending)

    @asyncio.coroutine
    def reload(self):
        """Wait for reload events and reload config when event set."""
        while 1:
            try:
                yield from self.reload_event.wait()
                self.log.info("Reloading configuration...")
            except asyncio.CancelledError:
                return
            finally:
                self.reload_event.clear()
            try:
                config = Config(self, self.filename, self.verbose)
                self.log.debug("New config instance %s" % config)
                yield from config.validate()
                self.config = config
                self.log.info("Done")
            except asyncio.CancelledError:
                return
            except Exception:
                self.log.exception("Error loading new config")

    @asyncio.coroutine
    def run(self):
        self._load_config()
        self.start_services()
        for prov in self.config.iter_providers():
            self.providers[prov.name] = prov
            yield from prov.start()
        reload_fut = asyncio.async(self.reload(), loop=self.loop)
        yield from self.stop_event.wait()
        self.log.info("Interrupted.")
        reload_fut.cancel()
        yield from reload_fut
        for obj in self._running_objects:
            obj.cancel()
        yield from asyncio.wait(self._running_objects,
                                return_when=futures.ALL_COMPLETED)
        if self._running_cleanups:
            yield from asyncio.wait(self._running_cleanups,
                                    return_when=futures.ALL_COMPLETED)
        for provider in self.providers.values():
            yield from prov.stop()
        self.log.info("Exit.")

    def job_updated(self, job):
        for cb in self.job_update_handlers:
            cb(job)

    def get_daemon_statistics(self):
        usage = resource.getrusage(resource.RUSAGE_SELF)
        return {"type": "daemon-statistics",
                "memory-used": getattr(usage, "ru_maxrss")}
Exemple #4
0
 def _load_config(self):
     self.config = Config(self, self.filename, self.verbose)
     self.config.configure_logging()
     self.log = logging.getLogger(__name__)
Exemple #5
0
 def load_config(self, filename):
     self.filename = filename
     self.config = Config(filename)
     self.start_streams()
     self.start_status_monitors()
Exemple #6
0
 def load_config(self):
     self.config = Config(self)
     self.log = logging.getLogger(__name__)
Exemple #7
0
class Root:
    def __init__(self, loop):
        self._running_objects = {}
        self._running_cleanups = []

        self.tasks = {}
        self.loop = loop
        self.providers = {}
        self.task_start_handlers = []
        self.task_end_handlers = []
        self.job_update_handlers = []
        self.stop_event = asyncio.Event()

    @asyncio.coroutine
    def run_obj(self, obj):
        try:
            self.log.debug("Running obj %s" % obj)
            yield from obj.run()
        except asyncio.CancelledError:
            self.log.info("Cancelled %s" % obj)
        except Exception:
            self.log.exception("Exception running %s" % obj)

    def start_task(self, task):
        for cb in self.task_start_handlers:
            cb(task)
        fut = self.start_obj(task)
        self.tasks[fut] = task
        fut.add_done_callback(self.tasks.pop)

    def start_obj(self, obj):
        fut = asyncio.async(self.run_obj(obj), loop=self.loop)
        fut.add_done_callback(self.schedule_cleanup)
        self._running_objects[fut] = obj
        return fut

    @asyncio.coroutine
    def run_cleanup(self, obj):
        try:
            yield from obj.cleanup()
        except Exception:
            self.log.exception("Exception in cleanup %s" % obj)

    def schedule_cleanup(self, fut):
        obj = self._running_objects.pop(fut)
        fut = asyncio.async(self.run_cleanup(obj), loop=self.loop)
        self._running_cleanups.append(fut)

    def start_services(self):
        for service in self.config.iter_instances("service"):
            self.start_obj(service)

    def load_config(self):
        self.config = Config(self)
        self.log = logging.getLogger(__name__)

    @asyncio.coroutine
    def wait_fs(self, fs):
        """Wait for futures.

        :param fs: dict where key is future and value is related object
        """
        self.log.debug("Waiting for %s" % fs.values())
        while fs:
            done, pending = yield from asyncio.wait(
                    list(fs.keys()), return_when=futures.FIRST_COMPLETED)
            for fut in done:
                if fut in fs:
                    del(fs[fut])

    @asyncio.coroutine
    def run(self):
        self.start_services()
        for prov in self.config.iter_providers():
            self.providers[prov.name] = prov
            prov.start()
        yield from self.stop_event.wait()
        self.log.info("Interrupted.")
        for obj in self._running_objects:
            obj.cancel()
        yield from self.wait_fs(self._running_objects)
        if self._running_cleanups:
            yield from asyncio.wait(self._running_cleanups,
                                    return_when=futures.ALL_COMPLETED)
        self.loop.stop()

    def job_updated(self, job):
        for cb in self.job_update_handlers:
            cb(job)

    def get_daemon_statistics(self):
        usage = resource.getrusage(resource.RUSAGE_SELF)
        return {"type": "daemon-statistics", "memory-used": getattr(usage, "ru_maxrss")}