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]