Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid crontab is created, but breaks database scheduler #748

Open
giolucasd opened this issue May 7, 2024 · 0 comments
Open

Invalid crontab is created, but breaks database scheduler #748

giolucasd opened this issue May 7, 2024 · 0 comments

Comments

@giolucasd
Copy link

giolucasd commented May 7, 2024

Summary:

There is validation while creating CrontabSchedule objects. But such validation allows crontabs that never runs, such as * * 1 31 2, to be created and used within PeriodicTask objects. Having such crontabs while using beat as separate process celery -A [project-name] beat -l info -S django lead to RuntimeError.

  • Django Version: 5.0.5
  • Celery Version: 5.4.0
  • Celery-Beat Version: 2.6.0

Exact steps to reproduce the issue:

  1. Create a CrontabSchedule:
problematic_crontab = {
    "minute": "*",
    "hour": "*",
    "day_of_week": "1",
    "day_of_month": "31",
    "month_of_year": "2",
}
schedule, _ = CrontabSchedule.objects.create(**problematic_crontab)
  1. Use the created schedule within a PeriodicTask:
PeriodicTask.objects.create(
    task="your_task",
    name="Problematic Task",
    crontab=schedule,
)
  1. Run beat scheduler:
celery -A [project-name] beat -l info -S django

Detailed information

I'm running django with celery and have a user newsletter that may be sent monthly, weekly or never. For that purpose, I decided to use 3 crontabs to do the job and the "never" crontab I chose was 31 of february instead of the classical year 3099. Project decisions apart, I believe that allowing the crontab creation while throwing a RuntimeError on that crontab existence is a bug and it led me to waisting way more time than I would have if the create validation already stated the problem.

The system runs on docker containers following cookiecutter-django patterns.

Logs:

[2024-05-07 12:10:10,954: CRITICAL/SpawnProcess-1] beat raised exception <class 'RuntimeError'>: RuntimeError('unable to rollover, time specification is probably invalid')
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/celery/apps/beat.py", line 113, in start_scheduler
    service.start()
  File "/usr/local/lib/python3.11/site-packages/celery/beat.py", line 643, in start
    interval = self.scheduler.tick()
               ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/celery/beat.py", line 339, in tick
    self.populate_heap()
  File "/usr/local/lib/python3.11/site-packages/celery/beat.py", line 313, in populate_heap
    is_due, next_call_delay = entry.is_due()
                              ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django_celery_beat/schedulers.py", line 136, in is_due
    return self.schedule.is_due(last_run_at_in_tz)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django_celery_beat/tzcrontab.py", line 41, in is_due
    rem_delta = self.remaining_estimate(last_run_at)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/celery/schedules.py", line 617, in remaining_estimate
    return remaining(*self.remaining_delta(last_run_at, ffwd=ffwd))
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/celery/schedules.py", line 604, in remaining_delta
    delta = self._delta_to_next(last_run_at,
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/celery/schedules.py", line 516, in _delta_to_next
    roll_over()
  File "/usr/local/lib/python3.11/site-packages/celery/schedules.py", line 505, in roll_over
    raise RuntimeError('unable to rollover, '
RuntimeError: unable to rollover, time specification is probably invalid
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant