jedcunningham commented on code in PR #69565:
URL: https://github.com/apache/airflow/pull/69565#discussion_r3540282353


##########
airflow-core/newsfragments/69565.improvement.rst:
##########


Review Comment:
   Just remove this completely. Only necessary for significant changes.



##########
airflow-core/tests/unit/models/test_taskinstance.py:
##########
@@ -3291,6 +3291,159 @@ def show(value):
             dag_maker.run_ti(ti.task_id, dag_run=dag_run, 
map_index=ti.map_index, session=session)
         assert outputs == expected_outputs
 
+    def test_map_xcom_wide_batched_expand(self, dag_maker, session):
+        """Wide XCom-driven expand goes through the batched add_all()/flush() 
path.
+
+        Exercises ``TaskMap.expand_mapped_task`` over a 20-element upstream 
XCom and
+        asserts the batched expansion creates exactly N mapped TIs with 
contiguous
+        ``map_index`` 0..N-1, the expected ``None`` (schedulable) state, and 
that the
+        returned instances are usable: they keep their ``.task`` (no merge() 
that drops
+        it), are attached to the session, and have ``dag_run`` primed so a 
later
+        ``ti.get_dagrun()`` -- as dependency evaluation makes per index -- is 
a cache hit
+        rather than an N+1 SELECT.
+        """
+        from sqlalchemy import event
+        from sqlalchemy.orm.base import NO_VALUE
+
+        width = 20
+        upstream_return = list(range(width))
+
+        with dag_maker(dag_id="xcom_wide", session=session, serialized=True) 
as dag:
+
+            @dag.task
+            def emit():
+                return upstream_return
+
+            @dag.task
+            def show(value):
+                return value
+
+            show.expand(value=emit())
+
+        dag_run = dag_maker.create_dagrun()
+        emit_ti = dag_run.get_task_instance("emit", session=session)
+        emit_ti.refresh_from_task(dag_maker.serialized_dag.get_task("emit"))
+        dag_maker.run_ti(emit_ti.task_id, dag_run=dag_run, session=session)
+
+        show_task = dag_maker.serialized_dag.get_task("show")
+        mapped_tis, max_map_index = TaskMap.expand_mapped_task(show_task, 
dag_run.run_id, session=session)

Review Comment:
   The merge()→add() switch — the main speedup — isn't pinned by a test. The 
query-count assertions only counts dag_run SELECTs, but merge()'s per-index 
SELECT hits task_instance. So reverting add()→merge() leaves both tests green. 
Wrapping the expand_mapped_task call in assert_queries_count(...) (already 
imported here) would guard it. Non-blocking.



##########
airflow-core/src/airflow/models/taskinstance.py:
##########
@@ -203,6 +203,33 @@ def _stop_remaining_tasks(*, task_instance: TaskInstance, 
task_teardown_map=None
             log.info("Not skipping teardown task '%s'", ti.task_id)
 
 
+def _add_and_prime_mapped_ti(
+    ti: TaskInstance,
+    task: Operator,
+    dag_run: DagRun,
+    *,
+    session: Session,
+    context_carrier: dict | None = None,
+) -> None:
+    """
+    Attach a newly-created mapped TI to the session and prime its ``dag_run`` 
cache.
+
+    Used by mapped-task expansion (``TaskMap.expand_mapped_task``,
+    ``DagRun._revise_map_indexes_if_mapped``) to persist a brand-new mapped TI 
without
+    the per-row SELECT that ``session.merge()`` would issue, and to prime 
``dag_run`` so
+    a later ``ti.get_dagrun()`` during dependency evaluation is a cache hit 
rather than
+    another per-TI SELECT.

Review Comment:
   ```suggestion
   ```
   
   imo too verbose. I'd toss it all, but if you want to keep it, simpler.



-- 
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]

Reply via email to