Fix dynamic dag_id resolution in TriggerDagRunOperator links#56973
Fix dynamic dag_id resolution in TriggerDagRunOperator links#56973hwang-cadent wants to merge 1 commit intoapache:mainfrom
TriggerDagRunOperator links#56973Conversation
|
Congratulations on your first Pull Request and welcome to the Apache Airflow community! If you have any issues or are unsure about any anything please check our Contributors' Guide (https://github.com/apache/airflow/blob/main/contributing-docs/README.rst)
|
TriggerDagRunOperator links
76a3ed7 to
331face
Compare
bfbe526 to
735f5af
Compare
d1598cd to
2c20224
Compare
|
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed in 5 days if no further activity occurs. Thank you for your contributions. |
0750c6b to
7f284d3
Compare
Resolve conflicts for PR apache#56973 (Fix dynamic dag_id resolution in TriggerDagRunOperator links): - serialized_objects.py: keep main structure, re-apply ARG_NOT_SET deserialization fix for _date fields - trigger_dagrun.py: drop openlineage_inject block to match main - test_trigger_dagrun.py: keep main imports; keep execute_complete tests; drop openlineage tests - test_task_runner.py: take main's imports, DagBag, listener fixtures, and test variants
pierrejeambrun
left a comment
There was a problem hiding this comment.
Something probably went wrong in the rebase process. The change set is huge.
Do you mind fixing the branch please so we can move forward.
Rebased on the latest apache/main and cleaned up. The change set now includes only the 4 PR-related files). Ready for review. Thank you for your patience. |
dabla
left a comment
There was a problem hiding this comment.
Looking good to me reviewed it from mobile though so I might have missed something.
dabla
left a comment
There was a problem hiding this comment.
Looking good to me apart from question if this change should also not be directly tested in test_serialized_objects instead of relying on indirect tests?
Good point. Currently tested indirectly through TriggerDagRunOperator tests. A direct unit test in test_serialized_objects.py for _deserialize_field_value() handling ARG_NOT_SET for date fields would be clearer. Should I add this test, or would you prefer to handle it in a follow-up? |
It think it would be better even though it's indirectly tested through TriggerDagRunOperator tests. So yes would add case in test_serialized_objects. |
Thanks for the feedback. I've added a direct test case test_deserialize_field_value_with_arg_not_set_for_date_fields in test_serialized_objects.py to verify that _deserialize_field_value returns NOTSET for ARG_NOT_SET date fields. This complements the indirect tests through TriggerDagRunOperator and improves test coverage. |
| ) | ||
| # Try to get the resolved dag_id from XCom first (for dynamic dag_ids) | ||
| trigger_dag_id = XCom.get_value(ti_key=ti_key, key=XCOM_DAG_ID) | ||
|
|
There was a problem hiding this comment.
Bug: if not trigger_dag_id: uses a truthiness check. If XCom.get_value returns an empty string "" (unlikely but possible), this would incorrectly fall through to the operator attribute fallback.
Should be:
if trigger_dag_id is None:
potiuk
left a comment
There was a problem hiding this comment.
The core idea of storing the resolved trigger_dag_id in XCom for dynamic link resolution is sound and addresses a real user-facing bug. However, there are several issues that should be addressed before merging:
- Architecture inconsistency in AF3: The
trigger_dag_idXCom is pushed inside the operator's_trigger_dag_af_3()(beforeDagRunTriggerExceptionis raised), whiletrigger_run_idis pushed intask_runner._handle_trigger_dag_run()(after successful trigger). This creates inconsistent state on trigger failure. - Bug in
get_linkfallback check: Uses truthiness (if not trigger_dag_id) instead of identity (if trigger_dag_id is None). - Separate concerns bundled together: The
serialized_objects.pydeserialization fix forARG_NOT_SETon_datefields is a distinct bug and should ideally be a separate PR for cleaner review and bisectability. - Test assertions weakened: Ordered call verification was replaced with unordered
assert_any_call, losing important ordering guarantees.
| trigger_dag_id = XCom.get_value(ti_key=ti_key, key=XCOM_DAG_ID) | ||
|
|
||
| # Fallback to operator attribute and rendered fields if not in XCom | ||
| if not trigger_dag_id: |
There was a problem hiding this comment.
This should become as @potiuk pointed out:
if trigger_dag_id is not None:
|
@hwang-cadent — This PR has new commits since the last review requesting changes from @potiuk. If you believe you've addressed the feedback, please ping the reviewer(s) to request a re-review. Thanks! Note: This comment was drafted by an AI-assisted triage tool and may contain mistakes. Once you have addressed the points above, an Apache Airflow maintainer — a real person — will take the next look at your PR. We use this two-stage triage process so that our maintainers' limited time is spent where it matters most: the conversation with you. |
|
@potiuk @dabla — addressed the review feedback in Comments 1, 2 and 4 (in
Comment 3 (separate PR):
Could you take another look when you get a chance? Thank you! |
|
Rebased on the latest Conflict resolution highlights:
Final scope of this PR (4 files, +138 / -22):
PR is now |
The operator link previously read ``trigger_dag_id`` only from the
operator attribute (and from rendered template fields on AF2). When the
``dag_id`` is resolved at runtime — for example from an XCom pull or a
non-trivial template — the static attribute does not reflect the actual
DAG that was triggered, so the "Triggered DAG" link in the UI points to
the wrong (or non-existent) DAG.
This change stores the resolved ``trigger_dag_id`` in XCom alongside
``trigger_run_id`` after a successful trigger, and updates
``TriggerDagRunLink.get_link()`` to prefer that XCom value before
falling back to the operator attribute / rendered fields.
Notes:
- For Airflow 3.x the XCom is pushed in
``task_runner._handle_trigger_dag_run`` (next to ``trigger_run_id``)
so both values share the same lifecycle and are not written when the
trigger fails.
- For Airflow 2.x the XCom is pushed in ``_trigger_dag_af_2`` after the
triggered ``DagRun`` is created.
- ``get_link`` uses an identity check (``trigger_dag_id is None``)
rather than truthiness so any explicit value pushed to XCom is
honored.
Tests:
- New ``test_extra_operator_link_with_dynamic_dag_id`` cases (AF2 & AF3)
verifying the link uses the resolved ``dag_id`` from XCom.
- Existing AF3 ``test_extra_operator_link`` updated to mock
``XCom.get_value`` (matches the actual call site).
- ``test_handle_trigger_dag_run`` and
``test_handle_trigger_dag_run_wait_for_completion`` updated with the
new ``SetXCom("trigger_dag_id")`` call in the expected ordered
sequence, keeping ``assert_has_calls`` ordering guarantees.
Fixes apache#46402
Fixes #46402 - Dynamic dag_id resolution in TriggerDagRunOperator links
Description
This PR addresses the issue where
TriggerDagRunOperatorlinks fail to work correctly when thedag_idis dynamically determined at runtime (e.g., from XCom values or complex templates). The current implementation only uses the statictrigger_dag_idattribute, which doesn't reflect the actual resolved dag_id when it's determined dynamically.Changes
XCOM_DAG_IDconstant to store the resolved dag_id in XCom during task executionTriggerDagRunLink.get_link()to prioritize XCom values over static operator attributes_trigger_dag_af_2) and 3.x (_trigger_dag_af_3) execution paths to push the resolved dag_id to XComTesting
Type of Change
^ Add meaningful description above
Read the Pull Request Guidelines for more information.
In case of fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
In case of a new dependency, check compliance with the ASF 3rd Party License Policy.
In case of backwards incompatible changes please leave a note in a newsfragment file, named
{pr_number}.significant.rstor{issue_number}.significant.rst, in airflow-core/newsfragments.