X-Git-Url: https://git.ralfj.de/saartuer.git/blobdiff_plain/83d646a505bed8c75eef15855da7046e5854106d..5a866fd8add83733d9e1cde55ecbd23f69661658:/libtuer.py diff --git a/libtuer.py b/libtuer.py index a655fcd..e31ce27 100644 --- a/libtuer.py +++ b/libtuer.py @@ -1,4 +1,4 @@ -import logging, logging.handlers, syslog, os +import logging, logging.handlers, os, time, queue, threading, subprocess, multiprocessing # logging function class Logger: @@ -9,13 +9,85 @@ class Logger: self.logger.setLevel(logging.INFO) self.handler = logging.handlers.SysLogHandler(address = '/dev/log', facility = logging.handlers.SysLogHandler.LOG_LOCAL0) self.logger.addHandler(self.handler) - def log (self, what): + + def log (self, lvl, what): thestr = "%s[%d]: %s" % (self.name,os.getpid(),what) print (thestr) - self.logger.info(thestr) + self.logger.log(lvl, thestr) + + def debug(self, what): + self.log(logging.DEBUG, what) + def info(self, what): + self.log(logging.INFO, what) + def warning(self, what): + self.log(logging.WARNING, what) + def error(self, what): + self.log(logging.ERROR, what) + def critical(self, what): + self.log(logging.CRITICAL, what) logger = Logger() -def log (what): - logger.log(what) - +# run a command asynchronously and log the return value if not 0 +# prefix must be a string identifying the code position where the call came from +def fire_and_forget (cmd, log, prefix): + def _fire_and_forget (cmd, log, prefix): + with open("/dev/null", "w") as fnull: + retcode = subprocess.call(cmd, stdout=fnull, stderr=fnull) + if retcode is not 0: + log("%sReturn code %d at command: %s" % (prefix,retcode,str(cmd))) + p = multiprocessing.Process(target=_fire_and_forget, args=(cmd,log,prefix)) + p.start() + +# Threaded callback class +class ThreadFunction(): + _CALL = 0 + _TERM = 1 + + def __init__(self, f): + self._f = f + self._q = queue.Queue() + self._t = threading.Thread(target=self._thread_func) + self._t.start() + + def _thread_func(self): + while True: + (cmd, data) = self._q.get() + # run command + if cmd == _CALL: + try: + self._f(*data) + except Exception: + logger.error("ThreadFunction: Got exception out of handler thread: %s" % str(e)) + elif cmd == _TERM: + assert data is None + break + else: + logger.error("ThreadFunction: Command %d does not exist" % cmd) + + def __call__(self, *arg): + self._q.put((self._CALL, arg)) + + def stop(self): + self._q.put((_TERM, None)) + self._t.join() + +# Thread timer-repeater class: Call a function every seconds +class ThreadRepeater(): + def __init__(self, f, sleep_time): + self._f = f + self._stop = False + self._sleep_time = sleep_time + self._t = threading.Thread(target=self._thread_func) + self._t.start() + + def _thread_func(): + while True: + if self._stop: + break + self._f() + time.sleep(sleep_time) + + def stop(self): + self._stop = True + self._t.join()