# # Copyright (C) 2019 Marko Myllynen # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # """PCP netcheck PMDA helper routines""" # pylint: disable=too-many-branches, too-many-locals, too-many-nested-blocks try: from time import perf_counter as time except ImportError: from time import time from time import sleep from threading import Thread from collections import OrderedDict class CheckRunner(object): """Check runner helper""" def __init__(self, dbg, log, err): """Constructor""" self._dbg = dbg self._log = log self._err = err self._objects = OrderedDict() self._threads = [] def add_module(self, module, obj, interval, align): """Add module to check""" self._objects[module] = (obj, interval, align) def start(self): """Start check runner threads""" if not self._threads: for module in self._objects: thread = Thread(target=self._run_module_check, name=module, args=(module, self._objects[module])) thread.daemon = True thread.start() self._threads.append(thread) sleep(0.01) # Yield def _run_module_check(self, module, params): """Run module check periodically""" obj, interval, align = params[0], params[1], params[2] aligned = "aligned" if align else "unaligned" self._log("Starting periodic %s check, %s interval: %d s." % (module, aligned, interval)) while True: start_time = time() try: obj.do_check() except Exception as error: # pylint: disable=broad-except self._err("%s: %s" % (module, str(error))) self._err("%s has failed, disabling!" % module) sleep_time = start_time + interval - time() if align else interval if sleep_time > 0: sleep(sleep_time)