From a9829078cce3789e010d33b193842da126531d24 Mon Sep 17 00:00:00 2001 From: Pierrick Brun Date: Mon, 16 Dec 2024 17:42:13 +0100 Subject: [PATCH] fix: :bug: make everything work with rrulesets --- rq_scheduler/utils.py | 6 +++--- tests/test_scheduler.py | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/rq_scheduler/utils.py b/rq_scheduler/utils.py index c9ee40c..4fbd404 100644 --- a/rq_scheduler/utils.py +++ b/rq_scheduler/utils.py @@ -36,12 +36,12 @@ def get_next_rrule_scheduled_time(rrule_string): """Calculate the next scheduled time by creating a rrule object with a rrule string""" timezone = dateutil.tz.UTC - rule = dateutil.rrule.rrulestr(rrule_string) - if rule._dtstart.tzinfo is None: + ruleset = dateutil.rrule.rrulestr(rrule_string, forceset=True) + if ruleset[0].tzinfo is None: now = datetime.now() # naive datetime else: now = datetime.now(tz=timezone) # aware datetime - next_time = rule.after(now) + next_time = ruleset.after(now) return next_time.astimezone(timezone) diff --git a/tests/test_scheduler.py b/tests/test_scheduler.py index 9d29d03..a98a504 100644 --- a/tests/test_scheduler.py +++ b/tests/test_scheduler.py @@ -1125,3 +1125,21 @@ def test_rrule_persisted_correctly_with_until(self): assert datetime_time.minute == 1 assert datetime_time.second == 0 assert datetime_time - now <= timedelta(hours=1), f"{datetime_time - now} is greater than 1 hour" + + def test_rruleset_persisted_correctly_with_dtstart(self): + """ + Ensure that rrule attribute gets correctly saved in Redis. + """ + # create a job that runs one minute past each whole hour + job = self.scheduler.rrule("DTSTART:20241126T154900Z\nRRULE:FREQ=HOURLY;WKST=MO;BYMINUTE=1;BYSECOND=0\nRRULE:FREQ=MINUTELY;INTERVAL=5;COUNT=2", say_hello) + job_from_queue = Job.fetch(job.id, connection=self.testconn) + self.assertEqual(job_from_queue.meta['rrule_string'], "DTSTART:20241126T154900Z\nRRULE:FREQ=HOURLY;WKST=MO;BYMINUTE=1;BYSECOND=0\nRRULE:FREQ=MINUTELY;INTERVAL=5;COUNT=2") + + # get the scheduled_time and convert it to a datetime object + unix_time = self.testconn.zscore(self.scheduler.scheduled_jobs_key, job.id) + datetime_time = from_unix(unix_time) + + # check that minute=1, seconds=0, and is within an hour + assert datetime_time.minute == 1 + assert datetime_time.second == 0 + assert datetime_time - datetime.utcnow() <= timedelta(hours=1), f"{datetime_time - datetime.utcnow()} is greater than 1 hour" \ No newline at end of file