Fix scheduler stalling when a Dag switches to a coarser schedule - #72250
Open
TSKVenkat wants to merge 2 commits into
Open
Fix scheduler stalling when a Dag switches to a coarser schedule#72250TSKVenkat wants to merge 2 commits into
TSKVenkat wants to merge 2 commits into
Conversation
Changing a Dag from an hourly to a daily cron stops it from ever being scheduled again. The scheduler keeps logging "run already exists; skipping dagrun creation" for a logical_date that is already taken, and never advances past it, so the Dag silently stops producing runs until someone deletes rows by hand. A guard for this already existed but only covered the zero-length intervals that CronTriggerTimetable leaves behind. The same collision happens whenever the previous run came from any finer schedule: aligning that run's interval end to the new, coarser cron lands back on the boundary the run already occupies. Comparing the proposed logical_date against the previous run's covers both cases and keeps the invariant the scheduler actually depends on, which is that a proposed run must be strictly later than the last one.
|
Congratulations on your first Pull Request and welcome to the Apache Airflow community! If you have any issues or are unsure about any anything please check our Contributors' Guide
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changing a Dag from an hourly to a daily cron stops it being scheduled again. The scheduler keeps logging
run already exists; skipping dagrun creationfor alogical_datethat is already taken and never advances past it, so the Dag silently stops producing runs until rows are deleted by hand._align_to_prevmaps the previous run's interval end back onto the new schedule. When the new cron is coarser than the one that produced that run, the result is the boundary the run already occupies, sonext_dagrun_infoproposes alogical_dateidentical to the existing run's.Reproduced on
main(3.4.0) with the reporter's scenario — an hourly run at2026-05-04 00:00with interval[00:00, 01:00), then a switch to0 0 * * *:and after the change:
Verified through the API the scheduler actually calls.
SchedulerJobRunnerreaches the timetable vianext_dagrun_info_v2(), and the baseTimetable.next_dagrun_info_v2delegates tonext_dagrun_infowithlast_dagrun_info.data_interval, so this is the live path rather than a helper reached only from tests:At the merge base
82215cf97c:With this change:
CronDataIntervalTimetableis reached when[scheduler] create_cron_data_intervalsis true, which is the configuration the report names.Scope of that check, stated plainly: this drives the scheduler's own timetable API, not a running scheduler against a metadata database. I could not stand a full scheduler up in this checkout — the Dag failed to deserialize in my local dev environment — so the last link, watching a
dag_runrow appear after the schedule change, is not something I have evidence for.A guard for this already existed, added in #66132, but it only covered the zero-length intervals
CronTriggerTimetableleaves behind (start == end). The collision is not specific to those: it happens whenever the previous run came from any finer schedule. Comparing the proposedlogical_dateagainst the previous run's expresses the invariant the scheduler actually depends on — a proposed run must be strictly later than the last one — and subsumes the zero-length case, so the existing test for it still passes unchanged.Tests:
test_coarser_schedule_does_not_re_emit_logical_datecovers the hourly-to-daily switch for both catchup settings. It fails onmain(2 failed) and passes with this change, whiletest_zero_length_last_interval_does_not_re_emit_logical_datepasses on both sides. Fullairflow-core/tests/unit/timetables/run: 253 passed, 1 pre-existing failure intest_workday_timetable.pycaused bypandasmissing from my environment (it fails identically on unmodifiedmain).closes: #66754
Was generative AI tooling used to co-author this PR?
Generated-by: Claude Code following the guidelines