Skip to content

Sort Task SDK EventsTimetable event dates unless presorted - #76181

Open
udsy19 wants to merge 1 commit into
apache:mainfrom
udsy19:fix/sdk-events-timetable-sort
Open

udsy19 wants to merge 1 commit into
apache:mainfrom
udsy19:fix/sdk-events-timetable-sort

Conversation

@udsy19

@udsy19 udsy19 commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

Why

The Task SDK EventsTimetable.__init__ (task-sdk/src/airflow/sdk/definitions/timetables/events.py) has the presorted flag inverted:

sorted(event_dates) if presorted else list(event_dates),

So with the default presorted=False, the dates are kept in the given order, contrary to the docstring ("if True, event_dates will be assumed to be in ascending order") and to the core airflow.timetables.events.EventsTimetable, which sorts if not presorted, as Airflow 2 did.

The order matters downstream: the encoder serializes event_dates as-is, and the core EventsTimetable.deserialize rebuilds with presorted=True. next_dagrun_info walks the list and takes the first event after the last run, so with event_dates=[Mar 1, Jan 1, Feb 1] it schedules Mar 1 first and the earlier events are silently skipped; the "N events between X and Y" summary is also wrong, since it reads the first and last items.

(Today this path is masked by the serialization KeyError: '_summary' that #69401 fixes; once that lands, unsorted event dates start dropping runs. In an end-to-end encode → core decode → next_dagrun_info loop with that fix applied by hand, [Mar 1, Jan 1, Feb 1] schedules only 2025-03-01 before this change and all three, in order, after.)

Fix

Swap the branches: list(event_dates) if presorted else sorted(event_dates).

Tests

New task-sdk/tests/task_sdk/definitions/timetables/test_events.py: dates are sorted by default, and kept as given (list or iterator) with presorted=True. All three fail on main and pass with the fix; tests/task_sdk/definitions/timetables/ passes.


Was generative AI tooling used to co-author this PR?
  • Yes. I reviewed the change and ran the tests above.

The Task SDK EventsTimetable inverted the presorted flag: it sorted the
event dates only when presorted=True and kept them in the given order by
default. The core EventsTimetable it is deserialized into is built with
presorted=True and walks event_dates in order, picking the first event
after the last run. An unsorted list therefore scheduled the latest event
first and silently dropped every earlier one.

Signed-off-by: Udaya Tejas <udayatejas2004@gmail.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant