amoghrajesh opened a new pull request, #70298:
URL: https://github.com/apache/airflow/pull/70298
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
<!--
Thank you for contributing!
Please provide above a brief description of the changes made in this pull
request.
Write a good git commit message following this guide:
https://chris.beams.io/posts/git-commit/
Please make sure that your code changes are covered with tests.
And in case of new features or big changes remember to adjust the
documentation.
For user-facing UI changes, please attach before/after screenshots (or a
short
screen recording) so reviewers can assess the visual impact.
Feel free to ping (in general) for the review if you do not see reaction for
a few days
(72 Hours is the minimum reaction time you can expect from volunteers) - we
sometimes miss notifications.
In case of an existing issue, reference it using one of the following:
* closes: #ISSUE
* related: #ISSUE
-->
---
##### Was generative AI tooling used to co-author this PR?
<!--
If generative AI tooling has been used in the process of authoring this PR,
please
change below checkbox to `[X]` followed by the name of the tool, uncomment
the "Generated-by".
-->
- [x] Yes - claude sonnet 4.6
<!--
Generated-by: [Tool Name] following [the
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
-->
---
### Important Note
**What "durable" and "deferrable" mean in the PR:** there are two different
reasons an operator can survive a crash, and they work in totally different
ways. "Durable" means the operator own code remembers where its job was and
reconnects to it instead of starting over, and this operates using task state
store in **synchronous mode**. "Deferrable" is running using a trigger, in
**asynchronous mode**. The end result looks similar to a user (nothing gets
redone), but one is a promise the operator has to keep and the other is just
how the system already works for everyone.
### What
Follow up to the merged `supports_durable_execution` badge PR (#67236). Now
that we have badget support, we should also have a few filters for ease of
navigation for two related-but-distinct capabilities: "durable" (anything that
survives a crash without redoing work -- `ResumableJobMixin`/manual-marker
operators, or deferrable ones) and "deferrable" (the narrower, deferrable-only
subset). The registry had no deferrable detection at all before this change.
### Current behaviour
The Registry only tracks `supports_durable_execution` (`ResumableJobMixin`
or the manual `__supports_durable_execution` marker coming in PR:
https://github.com/apache/airflow/pull/70291). Deferrable operators -- a much
more common capability across most cloud providers -- have no signal anywhere
in the pipeline, and there's no way to filter a provider's module list by
either capability.
### Proposed change
- **Detection**: `supports_deferrable(cls)` added to
`dev/registry/extract_parameters.py` -- checks for a `deferrable` constructor
parameter, reusing the existing `get_params_from_class()` machinery already
used for `parameters.json` (no new introspection needed).
- **Schema**: `supports_deferrable: bool = False` added to `ModuleContract`,
wired into `make_entry()` alongside `supports_durable_execution` (14 fields
total, kept as an independent signal, not merged into the existing one).
- **Frontend**: two independent badges on module cards ("Durable",
"Deferrable": teal/blue) shown per their own signal, since an operator can have
either, both, or neither. Two filter toggles on a provider's module list:
"Durable (includes deferrable)" and "Deferrable only".
### Changes of Note
- **The two filters are a deliberate union/subset pair, not independent
booleans.** "Durable" is `supports_durable_execution OR supports_deferrable` --
checking it shows every deferrable operator plus every
`ResumableJobMixin`/manual-marker operator, even ones that aren't deferrable.
"Deferrable only" is `supports_deferrable` alone, never OR'd. This means an
operator that is both durable and deferrable appears under *both* filters --
verified this is intentional and not confusing in practice, since the two
independent badges on the card explain why.
- The checkbox labels ("Durable (includes deferrable)" / "Deferrable only")
were chosen specifically to make that asymmetric containment relationship
(deferrable `⊆` durable, never the reverse) visible at the point of clicking,
rather than relying on a tooltip or a caption someone could miss.
- `is_deferrable` inheriting a parent's `__init__` unmodified still counts
as deferrable (unlike the `supports_durable_execution` manual-marker case,
which deliberately does *not* propagate to subclasses) -- inheriting an
unmodified constructor is a real functional guarantee the parameter still
works, whereas inheriting a durable-execution *claim* says nothing about
whether an overridden `execute()` still preserves it.
### Testing
- Built breeze to extract the provider data using: `breeze registry
extract-data`
- Built the actual Eleventy site against this real data and confirmed in the
rendered HTML: both badges appear on the right operator cards (e.g. Databricks'
page shows both a "Durable" and "Deferrable" badge on
`DatabricksRunNowOperator`), both filter checkboxes render with the intended
labels, and the `data-durable`/`data-deferrable` attributes are correctly
populated per the OR/non-OR logic on every module checked.
For current changes, this is the behaviour:
- **Databricks**: `DatabricksSubmitRunOperator` and
`DatabricksRunNowOperator` are both durable *and* deferrable.
`DatabricksNotebookOperator`, `DatabricksSQLStatementsOperator`,
`DatabricksTaskBaseOperator`, `DatabricksTaskOperator`, and
`DatabricksSQLStatementsSensor` are deferrable only. The rest of the provider's
operators/hooks/sensors are neither.
- **Apache Spark**: `SparkSubmitOperator` is durable but *not* deferrable
(no `deferrable` param) -- this is the single durable-only case across the
entire registry.
- **Google/BigQuery**: `BigQueryInsertJobOperator` is both durable and
deferrable, same pattern as Databricks.
- **Amazon/Redshift**: `RedshiftDataOperator` is both durable and deferrable.
- **Snowflake**: `SnowflakeSqlApiOperator` is both durable and deferrable.
Across the full dataset: 1779 modules total, 6 durable, 217 deferrable, 5
with both (the five listed above).
Some screenshots:
In this image, "Durable (includes deferrable)" is selected, and you can see
both durable + deferrable (BigQueryInsertJobOperator) and just deferrable ones
selected
<img width="1007" height="717" alt="image"
src="https://github.com/user-attachments/assets/b8313ece-8f0c-4c69-8057-459c6eed57f0"
/>
"Deferrable only selection":
<img width="1007" height="717" alt="image"
src="https://github.com/user-attachments/assets/f24eea5e-0eb0-4255-af3e-a7d6dcc8db76"
/>
Operator like snowflake has only one operator with both deferrable and
durable property, so its here:
<img width="1007" height="284" alt="image"
src="https://github.com/user-attachments/assets/9034c069-557c-4ae2-a9e1-305ce0a9784f"
/>
Spark is one of few operators with only "durable", and no deferrable option:
<img width="1007" height="284" alt="image"
src="https://github.com/user-attachments/assets/dbf6281f-23f3-449c-9800-0c19ad6be1e5"
/>
### What's next
Interactive click-through verification (actually toggling the checkboxes in
a running browser to confirm `filterModules()` behaves correctly) hasn't been
done -- only the generated HTML/data have been checked, not runtime JS
behavior. Registry-wide (cross-provider) discovery -- "which are all the
durable/deferrable operators across the whole registry," via a Pagefind search
filter facet -- was discussed and deliberately deferred to a separate follow-up.
---
* Read the **[Pull Request
Guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#pull-request-guidelines)**
for more information. Note: commit author/co-author name and email in commits
become permanently public when merged.
* For fundamental code changes, an Airflow Improvement Proposal
([AIP](https://cwiki.apache.org/confluence/display/AIRFLOW/Airflow+Improvement+Proposals))
is needed.
* When adding dependency, check compliance with the [ASF 3rd Party License
Policy](https://www.apache.org/legal/resolved.html#category-x).
* For significant user-facing changes create newsfragment:
`{pr_number}.significant.rst`, in
[airflow-core/newsfragments](https://github.com/apache/airflow/tree/main/airflow-core/newsfragments).
You can add this file in a follow-up commit after the PR is created so you
know the PR number.
--
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]