Build Dataproc submit job trigger arguments after template rendering - #71318
Build Dataproc submit job trigger arguments after template rendering#71318jerryzhou196 wants to merge 1 commit into
Conversation
067d1e8 to
a6b8b30
Compare
a6b8b30 to
fe9c096
Compare
|
Closing this — the change is wrong. With `start_from_trigger=True` the operator never runs on a worker, so `render_template_fields()` is never called on it. The scheduler reads `start_trigger_args` straight off the serialized DAG (`serialized_objects.py`, captured at parse time right after `init`) and `TaskInstance.defer_task()` builds the `Trigger` row from `trigger_kwargs`. Building the kwargs in `render_template_fields()` would ship an empty `trigger_kwargs` in the serialized DAG and the trigger would be instantiated without `job`/`region`/`project_id`. The un-rendered Jinja in `trigger_kwargs` is deliberate: `airflow-core/src/airflow/triggers/base.py` filters the operator's `template_fields` down to the keys present in `start_trigger_args.trigger_kwargs` that also exist on the trigger, and the triggerer calls `BaseTrigger.render_template_fields()` before running it. Rendering for this path happens in the triggerer, not on a worker. Follow-up PR narrows the `validate-operators-init` hook to sanction this pattern instead. Drafted-by: Claude Code (Opus 5) (no human review before posting) |
|
I checked this against One thing for the follow-up: narrowing the hook means the diagnostic in Drafted-by: Claude (Opus 5); reviewed by @mihirduvedi before posting |
DataprocSubmitJobOperator.__init__builtstart_trigger_argsfromjob,project_id,region,gcp_conn_id,impersonation_chainandrequest_id— all of them templatefields, so in the constructor they still hold the un-rendered Jinja expression. Those raw
strings were then what the operator advertised (and what got serialized) as the arguments
for starting directly in the triggerer.
Reproducer on
main:Rendering the fields afterwards does not help —
trigger_kwargskeeps the parse-time copy.start_trigger_argsis now built inrender_template_fields(), the first method that runsafter rendering, so it holds the rendered values. It is created with
dataclasses.replaceso the class-level template is left untouched for the next task built from the operator.
Regression tests are added for the rendered values and for the per-task isolation; the first
fails on
main.Removes the class from
scripts/ci/prek/validate_operators_init_exemptions.txt.related: #70296
Was generative AI tooling used to co-author this PR?
Generated-by: Claude Code (Opus 5) following the guidelines