Hi everyone,
I have been tracing an ordinary Airflow task end to end: how the Scheduler
decides it can run, how the executor queues it for execution by a worker,
and how its Task Instance state is persisted and reconsidered after failure
or clearing. While reading AIP-111, I became interested in how task loops
could reuse mapped Task Instance machinery while adding sequential behavior.

I then traced the mapped Task Instance clearing flow on main. My current
understanding is that map_index identifies each mapped instance, but it
does not make one index wait for the previous one. I also found that
relative selection follows the static edges in the Dag. Later iterations of
a loop would reuse the same task IDs and differ by map_index, so the
existing traversal would not discover higher indexes of the same task as
downstream nodes.

Before raising this question, I checked that baseline against upstream/main
at commit fb459dec5072051563d1924b57fa6f85fb265381.
Airflow's existing mapped-clear test passed for both queued and running
target Dag run states. It confirmed that clearing index 0 resets that
instance while index 1 remains successful. The mapped-relative test also
passed and confirmed that, for one mapped TaskGroup instance, relative
selection follows static Dag edges while preserving the corresponding map
index. I also found no public .loop() or max_iterations authoring surface
at that revision. I understand that these tests establish the current
dynamic-mapping baseline, not AIP-111 loop behavior.

A concrete example helped me understand the difference. In a loop,
iteration 2 may use the result of iteration 1 through loop.previous. If
iteration 1 is cleared and produces a different result, the old iteration 2
result, its old stop decision, and the loop completion result may no longer
be valid. Clearing iteration i should therefore preserve iterations before
i but invalidate and re-evaluate the loop from i onward.

Ordinary dynamic mapping is different: mapped[0] and mapped[1] are
independent siblings. Clearing mapped[0] should continue to leave mapped[1]
alone. This means suffix invalidation must be scoped to a loop, not
inferred from map_index alone.

I am particularly interested in how Airflow can support bounded iterative
workflows without turning the Dag itself into a cyclic or fully dynamic
graph.

I am not proposing a separate loop implementation. I saw the mention of a
working proof of concept in this thread, but I could not find a public
branch, tracker, or PR. Is this clear-and-re-evaluate behavior already
covered there? If not, would it be useful for me to prepare a focused
conformance-test slice for clear semantics once the implementation is
public? I could treat retry and Scheduler restart as follow-up cases after
the clear behavior is agreed.

For reference, I ran both tests at the revision above:

- airflow-core/tests/unit/models/test_dag.py
  TestDag::test_clear_set_dagrun_state_for_mapped_task
  Result: 2 passed (Dag run reset to QUEUED and RUNNING)

- airflow-core/tests/unit/models/test_taskinstance.py
  test_find_relevant_relatives[group-mapped-one]
  Result: 1 passed

Thanks,
Yash Jain

Reply via email to