From c9abd39f52da44c688b954f24f9efdf7b462f679 Mon Sep 17 00:00:00 2001 From: David Trattnig <david.trattnig@o94.at> Date: Wed, 18 Nov 2020 18:45:44 +0100 Subject: [PATCH] Remove stale timers. #41 --- src/core/control.py | 59 +++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/src/core/control.py b/src/core/control.py index c96bdd97..c2faf032 100644 --- a/src/core/control.py +++ b/src/core/control.py @@ -120,7 +120,7 @@ class SocketControlInterface: """ Starts the socket server """ - while(True): + while True: try: self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.server.bind((host, SocketControlInterface.PORT)) @@ -133,10 +133,9 @@ class SocketControlInterface: logger.info(SU.yellow(f'[ECI] Listening at {host}:{SocketControlInterface.PORT}')) self.server.listen() - while(True): + while True: (conn, client) = self.server.accept() - - while(True): + while True: r = SocketReader(conn) p = HttpStream(r) data = p.body_file().read() @@ -226,6 +225,7 @@ class EngineExecutor(Timer): self.dt = datetime.now() + timedelta(seconds=diff) self.func = func self.param = param + self.update_store() if diff < 0: msg = f"Timer '{self.timer_id}' is due in the past. Executing immediately ..." @@ -236,9 +236,7 @@ class EngineExecutor(Timer): self.exec_now() else: self.exec_timed() - self.start() - - self.update_store() + self.start() def wait_for_parent(self): @@ -246,9 +244,9 @@ class EngineExecutor(Timer): Child timers are dependend on their parents. So let's wait until parents are done with their stuff. """ if self.parent_timer and self.parent_timer.is_alive(): - while(self.parent_timer.is_alive()): + while self.parent_timer.is_alive(): self.logger.info(f"Timer '{self.timer_id}' is waiting for parent timer '{self.parent_timer.timer_id}' to finish") - time.sleep(0.1) + time.sleep(0.2) def exec_now(self): @@ -259,23 +257,16 @@ class EngineExecutor(Timer): self.wait_for_parent() thread = Thread(target = self.func, args = (self.param,)) thread.start() - + def exec_timed(self): """ Timed execution in a thread. """ def wrapper_func(param=None): - self.wait_for_parent() - - # Remove from store - self.logger.info(SU.green(f"Removing old timer with ID: {self.timer_id}")) - del EngineExecutor.timer_store[self.timer_id] - - # Call actual function + self.wait_for_parent() if param: self.func(param,) - else: self.func() - + else: self.func() Timer.__init__(self, self.diff, wrapper_func, (self.param,)) @@ -287,13 +278,13 @@ class EngineExecutor(Timer): if self.timer_id in EngineExecutor.timer_store: existing_command = EngineExecutor.timer_store[self.timer_id] if existing_command: - self.logger.info(SU.green(f"Cancelling previous timer with ID: {self.timer_id}")) + self.logger.debug(f"Cancelling previous timer with ID: {self.timer_id}") existing_command.cancel() if existing_command.child_timer: - self.logger.info(SU.green(f"Cancelling child timer with ID: {existing_command.child_timer.timer_id}")) + self.logger.debug(f"Cancelling child timer with ID: {existing_command.child_timer.timer_id}") EngineExecutor.timer_store[self.timer_id] = self - self.logger.info(SU.green(f"Created command timer with ID: {self.timer_id}")) + self.logger.debug(f"Created command timer with ID: {self.timer_id}") def is_alive(self): @@ -312,13 +303,32 @@ class EngineExecutor(Timer): return f"[{self.timer_id}] exec at {str(self.dt)} (alive: {self.is_alive()})" + @staticmethod + def remove_stale_timers(): + """ + Removes timers from store which have been executed and are older than one hour. + """ + timers = EngineExecutor.timer_store.values() + del_keys = [] + + for timer in timers: + if timer.dt < datetime.now() - timedelta(seconds=3600): + if not timer.child_timer or (timer.child_timer and not timer.child_timer.is_alive()): + timer.logger.debug(f"Removing already executed timer with ID: {timer.timer_id}") + del_keys.append(timer.timer_id) + + for timer_id in del_keys: + del EngineExecutor.timer_store[timer_id] + + @staticmethod def log_commands(): """ - Prints a list of active timers to the log. + Prints a list of active timers and inactive timer not older than one hour. """ timers = EngineExecutor.timer_store.values() msg = "\n [ ENGINE COMMAND QUEUE ]\n" + EngineExecutor.remove_stale_timers() if not timers: msg += "None available!\n" @@ -330,6 +340,3 @@ class EngineExecutor(Timer): msg += f" => {str(timer.child_timer)}\n" EngineExecutor.logger.info(msg + "\n") - - - -- GitLab