vatsrahul1001 opened a new pull request, #67720:
URL: https://github.com/apache/airflow/pull/67720

   Closes #67714.
   
   ## What was broken
   
   Open `@task_group` rendered with vertically-stacked internals and edges 
crossing the boundary in confusing ways whenever an internal task had a direct 
dependency on a node outside the group (an "escape edge" that bypassed the 
group's entry/exit interface). Dag execution was unaffected — purely a UI 
rendering issue.
   
   The reporter's minimal repro: with only `entry`/`exit` wired across the 
group boundary, Graph view rendered correctly. Adding two lines like 
`group_result["a2"] >> final_task_result` made the group's children stack 
vertically and dependency edges wrap around the boundary.
   
   ## Root cause
   
   Two interacting bugs in the ELK graph-layout refactor from #65031:
   
   1. **`hasUniformExternalConnectivity` was too lenient.** It fired whenever 
externally-connected children separately shared the same external *sources* OR 
the same external *targets*, instead of the canonical fan-in/fan-out pattern 
where every child has the same full `(sources, targets)` profile. The 
reporter's group had `a1` as an "entry" (external source `{start}`) and 
`a2`/`a3`/`group_done` as "exits" (external target `{final_task}`) — different 
profiles per child. The lenient check still returned `true`, triggering the 
collapse path on a group where the author had deliberately wired explicit 
escape edges.
   
   2. **`rewriteGroupEdges` was tuned for closed groups.** When the collapse 
path fired on an *open* group, it dropped all of the group's internal edges — 
leaving ELK with no internal-layout information for the children. That's what 
produced the vertical stacking.
   
   ## Fix
   
   * Tighten `hasUniformExternalConnectivity` to require every 
externally-connected child to share the same full `(sources, targets)` profile. 
Mixed entry/exit shapes (like the reporter's repro) now fall back to rendering 
individual crossing edges, preserving the author's explicit dependency intent. 
The canonical "cleanup group" fan-in/fan-out pattern that the optimization was 
designed for (every child has same upstream AND same downstream) still triggers 
the collapse.
   * Add a `preserveInternal` option to `rewriteGroupEdges`. The open-group 
call site sets it so the collapse optimization preserves internal edges for the 
subsequent extraction loop; the closed-group call site keeps the default (drop 
internals — they're not laid out when the group is collapsed).
   
   ## Tests
   
   New `elkGraphUtils.test.ts` covers:
   
   - `hasUniformExternalConnectivity` — vanilla TaskGroup, mixed-profile #67714 
trigger, canonical fan-in/fan-out
   - `generateElkGraph` for the #67714 repro: internal edges preserved AND 
escape edges rendered individually
   - `generateElkGraph` for the canonical fan-in/fan-out shape: collapse still 
fires, internal edges kept (exercises `preserveInternal: true`)
   - `generateElkGraph` regression guards: simple open TaskGroup, closed 
TaskGroup
   
   Verified the new tests fail against `main` without the fix and pass with it.
   
   ## Risk
   
   Targeted change to one file plus its new test. No API or schema changes. 
Behaviour change boundary is `hasUniformExternalConnectivity`'s return value on 
mixed-profile groups, which previously collapsed to a group-level edge and now 
renders individual edges. Closed groups and canonical fan-in/fan-out groups 
behave identically to before.
   
   cc @bbovenzi (author of #65031, original Graph-layout refactor)


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