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()
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")
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")}
def _load_config(self): self.config = Config(self, self.filename, self.verbose) self.config.configure_logging() self.log = logging.getLogger(__name__)
def load_config(self, filename): self.filename = filename self.config = Config(filename) self.start_streams() self.start_status_monitors()
def load_config(self): self.config = Config(self) self.log = logging.getLogger(__name__)
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")}