Skip to content

CrontabSchedule task with start_time but last_run_at is None will run before scheduled time #912

@WeJie

Description

@WeJie

Summary:

CrontabSchedule task, which last_run_at is None, with start_time(e.g. at 14:00) that scheduled run at fixed time(e.g. at 15:00) will run immediately at celery beat start(or reload), if start_time < right now(e.g. at 14:02) < schedule time.

Exact steps to reproduce the issue:

let's say right now is 14:00 today

  1. Stop celery beat.
  2. Create PeriodicTask with start_time is now - 2mins with CrontabSchedule 0 15 * * *
  3. Start celery beat.

Detailed information

When last_run_at is None and start_time is not None, current logic only consider interval typed of task, but does not cater tasks run at every fixed time.

class ModelEntry(ScheduleEntry):
    def __init__(self, model, app=None):
        ....
        if not model.last_run_at:
            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
            # and avoid the heap block.
            if self.model.start_time:
                # issue: because the last_run_at is way too past, fixed time task will 
                # run immediately like it already pass the last schedule time, which is actually not.
                model.last_run_at = model.last_run_at \
                    - datetime.timedelta(days=365 * 30)
  • Celery Version: 5.5.3
  • Celery-Beat Version: 2.8.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions