Skip to content

Commit

Permalink
fix long period task will never be triggered (#717)
Browse files Browse the repository at this point in the history
* fix long period task will never be triggered

* fix (schedulers): when model.date_changed is None, use _default.now()

* test (schedulers): add test for when model.last_run_at is None

* test (scheduler): revise the comment

---------

Co-authored-by: chentiantian <[email protected]>
  • Loading branch information
daydaychen and chentiantian authored Nov 7, 2024
1 parent c2cd119 commit 476be26
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
2 changes: 1 addition & 1 deletion django_celery_beat/schedulers.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def __init__(self, model, app=None):
self.model = model

if not model.last_run_at:
model.last_run_at = self._default_now()
model.last_run_at = model.date_changed or self._default_now()
# if last_run_at is not set and
# model.start_time last_run_at should be in way past.
# This will trigger the job to run at start_time
Expand Down
49 changes: 49 additions & 0 deletions t/unit/test_schedulers.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,55 @@ def test_entry_and_model_last_run_at_with_utc_no_use_tz(self, monkeypatch):
if hasattr(time, "tzset"):
time.tzset()

@override_settings(
USE_TZ=False,
DJANGO_CELERY_BEAT_TZ_AWARE=False
)
@pytest.mark.usefixtures('depends_on_current_app')
@timezone.override('Europe/Berlin')
@pytest.mark.celery(timezone='Europe/Berlin')
def test_entry_and_model_last_run_at_when_model_changed(self, monkeypatch):
old_tz = os.environ.get("TZ")
os.environ["TZ"] = "Europe/Berlin"
if hasattr(time, "tzset"):
time.tzset()
assert self.app.timezone.key == 'Europe/Berlin'
# simulate last_run_at from DB - not TZ aware but localtime
right_now = datetime.utcnow()
# make sure to use fixed date time
monkeypatch.setattr(self.Entry, '_default_now', lambda o: right_now)
m = self.create_model_crontab(
crontab(minute='*/10')
)
m.save()
e = self.Entry(m, app=self.app)
e.save()
m.refresh_from_db()

# The just created model has no value for date_changed
# so last_run_at should be set to the Entry._default_now()
assert m.last_run_at == e.last_run_at

# If the model has been updated and the entry.last_run_at is None,
# entry.last_run_at should be set to the value of model.date_changed.
# see #717
m2 = self.create_model_crontab(
crontab(minute='*/10')
)
m2.save()
m2.refresh_from_db()
assert m2.date_changed is not None
e2 = self.Entry(m2, app=self.app)
e2.save()
assert m2.last_run_at == m2.date_changed

if old_tz is not None:
os.environ["TZ"] = old_tz
else:
del os.environ["TZ"]
if hasattr(time, "tzset"):
time.tzset()

@override_settings(
USE_TZ=False,
DJANGO_CELERY_BEAT_TZ_AWARE=False,
Expand Down

0 comments on commit 476be26

Please sign in to comment.