Add durable execution to DatabricksSubmitRunOperator - #68974
Merged
amoghrajesh merged 8 commits intoJun 30, 2026
Conversation
amoghrajesh
requested review from
Copilot,
eladkal,
kaxil,
pankajkoti and
vikramkoka
June 25, 2026 09:05
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds crash-safe (“durable”) synchronous execution to DatabricksSubmitRunOperator by integrating the Task SDK’s ResumableJobMixin / task state store so retries can reconnect to an existing Databricks run instead of submitting duplicates.
Changes:
- Extend
DatabricksSubmitRunOperatorwithResumableJobMixinhooks (submit_job,get_job_status, etc.) and add adurableoption (default-enabled on Airflow 3.3+). - Add/adjust unit tests to cover durable reconnect / short-circuit behavior and to keep legacy tests working by disabling durable where
execute(None)is used. - Document durable execution semantics and the
durable=Falseopt-out.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 8 comments.
| File | Description |
|---|---|
| providers/databricks/src/airflow/providers/databricks/operators/databricks.py | Implements durable synchronous execution via ResumableJobMixin and adds reconnect-aware polling/logging behavior. |
| providers/databricks/tests/unit/databricks/operators/test_databricks.py | Updates existing tests to pass durable=False where needed; adds a new durable-focused test suite. |
| providers/databricks/docs/operators/submit_run.rst | Documents durable execution behavior, version requirements, and opt-out configuration. |
kaxil
reviewed
Jun 25, 2026
1 task
kaxil
approved these changes
Jun 26, 2026
uranusjr
reviewed
Jun 29, 2026
uranusjr
approved these changes
Jun 29, 2026
Contributor
Author
|
Thanks for your reviews, merging this. |
1 task
karenbraganz
pushed a commit
to karenbraganz/airflow
that referenced
this pull request
Jun 30, 2026
* Add durable execution to DatabricksSubmitRunOperator * Add durable execution to DatabricksSubmitRunOperator * bot review * fixing mypy * kaxil comments * fixing CI * comments from tp
75 tasks
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.
Was generative AI tooling used to co-author this PR?
Next application of resumablejobmixin!
Why we are doing this
DatabricksSubmitRunOperatorsubmits a run to Databricks, gets back a run id, and then polls synchronously on the worker until the run finishes. That run id lives only in the worker process. If the worker crashes or is preempted mid-poll (eviction, OOM, or whatever reason), Airflow retries the task in a fresh process with no memory of the run id, so it submits a brand-new run. The original run keeps executing on Databricks, orphaned, while the retry runs a duplicate.For long-running Databricks jobs this means paying twice (or more) for the same work, and it is a real operational pain for users running multi-hour jobs. Deferrable mode already protects the long wait (the Triggerer holds the run id), but a large share of users do not run a Triggerer, and deferrable optimizes the worker slot rather than the cost of the external job. This change makes the plain synchronous path crash safe with no new infrastructure.
Benefits this will bring in
Approach
The operator now builds on the AIP-103 task state store. On the first run it persists the Databricks run id to the task state store before polling begins. On a retry it reads that id back and inspects the run's current state:
The task state store is scoped to the task instance and survives across retries, which is what makes the reconnect possible. Deferrable mode is unchanged and takes precedence when it is enabled.
Backcompat
How to opt out
Set
durable=Falseon the operator:This restores the previous behavior: always submit a fresh run on retry and never touch the task state store. It can also be set through
default_argsto opt out across a whole Dag or deployment.Testing
Running this dag earlier and killing worker mid run would look like this:
Before my changes
Killed mid run:
First run:
Worker comes back up:
Extra run submitted now due to that:
After my changes:
First run:
Worker comes back up:
Just one job run:
Tried killing the job and it kills external job too:
{pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.