-
Notifications
You must be signed in to change notification settings - Fork 472
Fix CrontabSchedule task run before schedule time #913
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
base: main
Are you sure you want to change the base?
Conversation
Co-authored-by: Copilot <[email protected]>
The origin unittest use loop to confirm task m1 will not be blocked by task m2. This is not a stable way, the test sometimes passed, sometimes failed. Because m1 sechdued at every 3s, it may or may not schdeuled at after m2' start_time 1s, but current time is before m2' start_time 2s, which make the test failed, but not as expected.
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #913 +/- ##
==========================================
+ Coverage 88.19% 88.21% +0.02%
==========================================
Files 32 32
Lines 1008 1010 +2
Branches 105 106 +1
==========================================
+ Hits 889 891 +2
Misses 101 101
Partials 18 18 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
@alirafiei75 would you mind having a look when available again? |
Co-authored-by: Copilot <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR ensures crontab tasks with a defined start_time do not run before that time by adjusting last_run_at and adding unit tests to cover the scenario.
- Added tests to verify crontab schedules respect
start_timebefore becoming due. - Updated
ModelEntryinitialization to setlast_run_attostart_timefor crontab schedules. - Enhanced tick-based tests to confirm the scheduler heap is not blocked by tasks before their
start_time.
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| t/unit/test_schedulers.py | New tests covering crontab start_time behavior and heap ordering |
| django_celery_beat/schedulers.py | Scheduler logic updated to use start_time for crontab entries, preventing early runs |
| time.sleep(3) | ||
| s.tick() |
Copilot
AI
Jul 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using time.sleep in tests can slow down the suite and introduce flakiness; consider simulating time progression by mocking time.monotonic or the scheduler’s time source instead.
| time.sleep(3) | |
| s.tick() | |
| with patch('time.monotonic', side_effect=lambda: monotonic() + 3): | |
| s.tick() |
Copilot uses AI. Check for mistakes.
| time.sleep(3) | ||
| s.tick() | ||
| assert s._heap[0][2].name == m1.name | ||
| with patch('time.monotonic', side_effect=lambda: monotonic() + 54): |
Copilot
AI
Jul 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Patching time.monotonic this way may lead to recursion if monotonic refers to the patched function; patch the scheduler module’s reference or call the original time.monotonic inside the side effect to avoid infinite recursion.
| with patch('time.monotonic', side_effect=lambda: monotonic() + 54): | |
| original_monotonic = time.monotonic | |
| with patch('time.monotonic', side_effect=lambda: original_monotonic() + 54): |
Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| if isinstance(model.schedule, schedules.schedule) \ | ||
| and not isinstance(model.schedule, schedules.crontab): |
Copilot
AI
Oct 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The condition logic is hard to read with the line break and negation. Consider refactoring to improve clarity, such as checking for crontab first or using a more descriptive variable.
| if isinstance(model.schedule, schedules.schedule) \ | |
| and not isinstance(model.schedule, schedules.crontab): | |
| is_interval_schedule = ( | |
| isinstance(model.schedule, schedules.schedule) | |
| and not isinstance(model.schedule, schedules.crontab) | |
| ) | |
| if is_interval_schedule: |
Copilot uses AI. Check for mistakes.
| if isinstance(model.schedule, schedules.schedule) \ | ||
| and not isinstance(model.schedule, schedules.crontab): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if isinstance(model.schedule, schedules.schedule) \ | |
| and not isinstance(model.schedule, schedules.crontab): | |
| if isinstance(model.schedule, (schedules.crontab, schedules.schedule)): |
% ruff rule PIE810 # Shorter, faster, easier to understand/
| # 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. | ||
| model.last_run_at = model.last_run_at \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PEP8 suggests avoiding backslashes in Python code because whitespace to the right of the backslash breaks the code on a change that is invisible to the reader. Put the contents on a single line and then allow ruff format or psf/black to reformat the code.
This fix cater the scenairo that crontab tasks(run at every fixed time) with last_run_at is None and start_time is not None run before the scheduled time.
Fix for #912
Unit test included.