seanghaeli opened a new pull request, #68919:
URL: https://github.com/apache/airflow/pull/68919

   ## Why
   
   This re-introduces the **deadline read/serialization robustness** slice of 
#66608 (fully reverted in #68909), as an independent, token-neutral change. It 
contains none of the callback context-delivery or execution-API token-scope 
work from #66608 — only making the deadline read and (de)serialization paths 
resilient to dynamic (`VariableInterval`) and malformed stored data.
   
   The motivating bug: `DeadlineAlert.interval` is a JSON column holding the 
Airflow-serialized interval (a fixed `timedelta` or a dynamic 
`VariableInterval`), not a plain number. The `/ui/dags/{dag_id}/deadlineAlerts` 
response declared `interval: float`, so any alert with a serialized-dict 
interval failed Pydantic validation and the endpoint returned **500**, breaking 
the run-page deadline status badge.
   
   ## What
   
   - **Interval coercion** (`datamodels/ui/deadline.py`): `interval` becomes 
`float | None` with a `before` validator that returns seconds for a fixed 
`timedelta` and `None` for a dynamic `VariableInterval`.
   - **Sortable keys** (`routes/ui/deadlines.py`): drop `interval` from 
`order_by` — sorting a JSON column sorts by structure, not duration.
   - **Deserialization** (`serialization/decoders.py`, 
`serialization/definitions/deadline.py`): route by `__class_path` ahead of 
`reference_type` (custom refs may share a builtin's class name); raise a clear 
error for a reference with no importable `__class_path` instead of an opaque 
`KeyError`.
   - **`__repr__` safety** (`models/deadline.py`, `models/deadline_alert.py`): 
never raise — guard the `dagrun` relationship (FK can be set while the 
relationship is `None` post-cascade-delete) and handle the dict-shaped interval.
   - **Prune guard** (`models/deadline.py`): `prune_deadlines` explicitly 
excludes `~Deadline.missed` so a missed deadline's queued callback is never 
cascade-deleted.
   
   ## Scope notes
   
   Deliberately **excluded** from this PR (to keep it reviewable and 
token-neutral), to follow in separate PRs:
   - The `handle_miss` change that injects routing identifiers into 
`callback.data` (part of callback context delivery).
   - The `min_runs > max_runs` fail-fast validation (a distinct concern).
   
   ## Tests
   
   `test_deadlines.py` (interval coercion + order-by rejection), 
`test_deadline_alert.py` / `test_deadline.py` (repr never raises), 
`test_deadline_reference_registry.py` (`__class_path` precedence + 
missing-class-path error), `test_prune_deadlines.py` (missed deadlines survive 
prune).
   
   Verified locally in Breeze: 113 passed.
   
   Generated-by: Claude Code (Opus via Claude Code) on behalf of Sean Ghaeli
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to