From be69763f480fcb84f2a6e0c8b5fbfce10ec62f43 Mon Sep 17 00:00:00 2001 From: brb Date: Mon, 24 Jul 2023 09:37:41 +0200 Subject: [PATCH] added cronjob decorator code --- code/cron.py | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 code/cron.py diff --git a/code/cron.py b/code/cron.py new file mode 100644 index 0000000..aeffc7b --- /dev/null +++ b/code/cron.py @@ -0,0 +1,53 @@ +from cron_converter import Cron +from configparser import ConfigParser +from pathlib import Path +from datetime import datetime +import dateutil +import time +import functools +import logging + +# load default values +config = ConfigParser() +config.read(Path(__file__).parent / 'defaults.ini') +SCHEDULE = config.get('cron', 'schedule') +TZ = config.get('cron', 'tz') + + +def cronjob( + schedule: str = SCHEDULE, + tz: str = TZ +): + """ + decorator for running function as a cronjob. + """ + logging.info(f'started cronjob with schedule {schedule} and tz {tz}') + + def decorator_cronjob(func): + @functools.wraps(func) + def wrapper_cronjob(*args, **kwargs): + scheduler = Cron(schedule).schedule(timezone_str=tz) + trigger_time = scheduler.next() + while True: + while trigger_time > datetime.now(tz=dateutil.tz.gettz(tz)): + # waiting loop + time.sleep(1) + # actual execution + try: + func(*args, **kwargs) + except Exception as e: + logging.warning(f'failed executing {func}: {e}') + raise + else: + # update trigger time + trigger_time = scheduler.next() + return wrapper_cronjob + return decorator_cronjob + + +if __name__ == '__main__': + @cronjob(schedule='* * * * *', tz=TZ) + def test_loop(msg: str): + print(msg) + + test_loop('hello world')