Return tuple of ``(is_due, next_time_to_run)``. If :setting:`beat_cron_starting_deadline` has been specified, the scheduler will make sure that the `last_run_at` time is within the deadline. This prevents tasks that could have been run according to the crontab, but
(self, last_run_at: datetime)
| 639 | return remaining(*self.remaining_delta(last_run_at, ffwd=ffwd)) |
| 640 | |
| 641 | def is_due(self, last_run_at: datetime) -> tuple[bool, datetime]: |
| 642 | """Return tuple of ``(is_due, next_time_to_run)``. |
| 643 | |
| 644 | If :setting:`beat_cron_starting_deadline` has been specified, the |
| 645 | scheduler will make sure that the `last_run_at` time is within the |
| 646 | deadline. This prevents tasks that could have been run according to |
| 647 | the crontab, but didn't, from running again unexpectedly. |
| 648 | |
| 649 | Note: |
| 650 | Next time to run is in seconds. |
| 651 | |
| 652 | SeeAlso: |
| 653 | :meth:`celery.schedules.schedule.is_due` for more information. |
| 654 | """ |
| 655 | |
| 656 | rem_delta = self.remaining_estimate(last_run_at) |
| 657 | rem_secs = rem_delta.total_seconds() |
| 658 | rem = max(rem_secs, 0) |
| 659 | due = rem == 0 |
| 660 | |
| 661 | deadline_secs = self.app.conf.beat_cron_starting_deadline |
| 662 | has_passed_deadline = False |
| 663 | if deadline_secs is not None: |
| 664 | # Make sure we're looking at the latest possible feasible run |
| 665 | # date when checking the deadline. |
| 666 | last_date_checked = last_run_at |
| 667 | last_feasible_rem_secs = rem_secs |
| 668 | while rem_secs < 0: |
| 669 | last_date_checked = last_date_checked + abs(rem_delta) |
| 670 | rem_delta = self.remaining_estimate(last_date_checked) |
| 671 | rem_secs = rem_delta.total_seconds() |
| 672 | if rem_secs < 0: |
| 673 | last_feasible_rem_secs = rem_secs |
| 674 | |
| 675 | # if rem_secs becomes 0 or positive, second-to-last |
| 676 | # last_date_checked must be the last feasible run date. |
| 677 | # Check if the last feasible date is within the deadline |
| 678 | # for running |
| 679 | has_passed_deadline = -last_feasible_rem_secs > deadline_secs |
| 680 | if has_passed_deadline: |
| 681 | # Should not be due if we've passed the deadline for looking |
| 682 | # at past runs |
| 683 | due = False |
| 684 | |
| 685 | if due or has_passed_deadline: |
| 686 | rem_delta = self.remaining_estimate(self.now()) |
| 687 | rem = max(rem_delta.total_seconds(), 0) |
| 688 | return schedstate(due, rem) |
| 689 | |
| 690 | def __eq__(self, other: Any) -> bool: |
| 691 | if isinstance(other, crontab): |
nothing calls this directly
no test coverage detected