From: Ralf Jung Date: Thu, 24 Oct 2013 17:48:28 +0000 (+0200) Subject: libtuer: add a fire_and_forget for python functions X-Git-Url: https://git.ralfj.de/saartuer.git/commitdiff_plain/91c3451346afd2d5c1ae5b7600acc77b540c9e3b?ds=inline libtuer: add a fire_and_forget for python functions --- diff --git a/libtuer.py b/libtuer.py index 1789b90..835bf6d 100644 --- a/libtuer.py +++ b/libtuer.py @@ -58,16 +58,26 @@ class Logger: logger = Logger() +# run a Python command asynchronously +def fire_and_forget(f): + def _fire_and_forget(): + try: + f() + except Exception as e: + logger.critical("fire_and_forget: Got exception out of callback: %s" % str(e)) + logger.debug(traceback.format_exc()) + t = threading.Thread(target=_fire_and_forget) + t.start() + # 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 (): +def fire_and_forget_cmd (cmd, log, prefix): + def _fire_and_forget_cmd (): with open("/dev/null", "w") as fnull: retcode = subprocess.call(cmd, stdout=fnull, stderr=fnull) if retcode is not 0: logger.error("%sReturn code %d at command: %s" % (prefix,retcode,str(cmd))) - t = threading.Thread(target=_fire_and_forget) - t.start() + fire_and_forget(_fire_and_forget_cmd) # Threaded callback class class ThreadFunction(): diff --git a/statemachine.py b/statemachine.py index a3c4aff..0f325a8 100644 --- a/statemachine.py +++ b/statemachine.py @@ -11,7 +11,7 @@ def play_sound (what): logger.error("StateMachine: Unable to list sound files in %s" % (SOUNDS_DIRECTORY+what)) return soundfile = SOUNDS_DIRECTORY + what + '/' + random.choice(soundfiles) - fire_and_forget ([SOUNDS_PLAYER,soundfile], logger.error, "StateMachine: ") + fire_and_forget_cmd ([SOUNDS_PLAYER,soundfile], logger.error, "StateMachine: ") # StateUnlocking constants @@ -175,8 +175,7 @@ class StateMachine(): def _close_after_time(): time.sleep(FALLBACK_LEAVE_DELAY_LOCK) self.actor().act(Actor.CMD_LOCK) - t = threading.Thread(target=_close_after_time) - t.start() + fire_and_forget(_close_after_time) # not calling superclass because we want to stay in fallback mode def handle_wakeup_event(self): # blink red LED