The cron scheduler has been made more robust against changes in the
system clock (caused by e.g. DST changes, NTP syncs or manual setting).

A more granular management for cronjob events has been introduced, now
supporting a `TIME_SYNC` event besides the usual `STOP`. When the cron
scheduler detects a system clock drift (i.e. the timestamp offset before
and after a blocking wait is >1 sec) then all the cronjobs are notified
and forced to refresh their state.
This commit is contained in:
Fabio Manganiello 2022-04-28 00:57:49 +02:00
parent 820a1c8184
commit 41d0725ebf
Signed by: blacklight
GPG key ID: D90FBA7F76362774
3 changed files with 148 additions and 63 deletions
tests/etc/scripts

View file

@ -2,25 +2,34 @@ import datetime
from platypush.cron import cron
from tests.test_cron import tmp_files, tmp_files_ready, \
test_timeout, expected_cron_file_content
from tests.test_cron import test_timeout, cron_queue
def make_cron_expr(cron_time: datetime.datetime):
return '{min} {hour} {day} {month} * {sec}'.format(
min=cron_time.minute,
hour=cron_time.hour,
day=cron_time.day,
month=cron_time.month,
sec=cron_time.second,
)
# Prepare a cronjob that should start test_timeout/2 seconds from the application start
cron_time = datetime.datetime.now() + datetime.timedelta(seconds=test_timeout/2)
cron_expr = '{min} {hour} {day} {month} * {sec}'.format(
min=cron_time.minute, hour=cron_time.hour, day=cron_time.day,
month=cron_time.month, sec=cron_time.second)
cron_time = datetime.datetime.now() + datetime.timedelta(seconds=test_timeout / 2)
@cron(cron_expr)
@cron(make_cron_expr(cron_time))
def cron_test(**_):
"""
Simple cronjob that awaits for ``../test_cron.py`` to be ready and writes the expected
content to the monitored temporary file.
"""
files_ready = tmp_files_ready.wait(timeout=test_timeout)
assert files_ready, \
'The test did not prepare the temporary files within {} seconds'.format(test_timeout)
cron_queue.put('cron_test')
with open(tmp_files[0], 'w') as f:
f.write(expected_cron_file_content)
# Prepare another cronjob that should start 1hr + test_timeout/2 seconds from the application start
cron_time = datetime.datetime.now() + datetime.timedelta(
hours=1, seconds=test_timeout / 2
)
@cron(make_cron_expr(cron_time))
def cron_1hr_test(**_):
cron_queue.put('cron_1hr_test')