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

   First off: why is this needed, wasn't loops landed and working? "Yes, but."
   Part of the goal with the data-modelling changes for task loops (AIP-111)
   is to support dynamic graphs (AIP-113) and other dynamic things, such as
   choosing to allow loops inside loops (currently a parse error), with no 
future
   migrations or data modelling changes needed. This change lets us enable these
   features without expensive recursive queries in TIDep evaulation etc. And why
   now? By getting this change in before 3.4.0 enters the RC stage, while we can
   still change the migration "at zero-cost". And adding it as a migration in 
3.5
   would involve a (possibly costly) migration.
   
   So the meat of the change:
   
   Finding the task instances that sit inside one iteration of a loop currently
   means finding every region of the loop's fork chain (a fork is when a loop is
   cleared part way through and some iterations run a-fresh),  plus everything
   nested under that iteration, however deep. The previous lookup resolved those
   region ids with two recursive CTEs and then passed them to the task_instance
   query as literal lists. The nested list holds every region under the
   iteration, whichever task is being read, so once something under an iteration
   can fan out again (nested loops, or dynamic graphs inside a loop) its size
   grows with the product of those widths. Every lookup hits this path: the
   scheduler's trigger-rule check of a loop task repeats it on each pass until
   the task is ready, and every XCom read from inside a loop pays it on the API
   server. Measured with 5,000 regions under one iteration, a lookup that 
returns
   one row took about 30 ms on PostgreSQL and MySQL, almost all of it building,
   sending and parsing the list; with 50,000 it took about 550 ms.
   
   Two columns on dynamic_region lets us get the same result but without
   recursion. `family_root_id` is the id of the first region of a fork chain, so
   a chain is one equality column comparisson. `path` contains, for each 
ancestor
   from the top, its family root and the index the region sits at inside it, so
   everything under one iteration of a loop shares a byte prefix and is one 
range
   of an index. The lookup becomes a UNION ALL of two joins from task_instance
   to dynamic_region, each driven by its own index; a single OR across the two
   legs gives the planner no such choice. Its cost no longer depends on how many
   regions sit under the iteration. The hook that fills the columns rejects a
   fork whose parent differs from its source's, because both the family equality
   and the prefix range rely on every member of a chain sharing one position.
   
   Region inserts are rare next to task instance reads and writes, so the hook
   and the two extra indexes cost comparitavely little.
   
   The columns are NOT NULL so that raw inserts which skip the ORM fail loudly
   instead of writing rows the lookup would silently miss. They are added to the
   migration that creates dynamic_region, which has only shipped in a beta, so 
no
   backfill is needed. A 3.4.0b1 database already ran that migration without 
them
   so users in that situation will need to downgrade to 3.3 and upgrade again,
   or reset the database. Nesting is capped at ten ancestors, which sets the
   200-byte path width on MySQL. The cap is a chosen bound rather than an index
   limit, and authoring already rejects nested loops, so current real depth is 
far lower.
   
   In order to allow more easily resizing this column on MySQL in the future if
   we want or need to, the length needs to be over 255 bytes (as InnoDB stores
   VARBINARY with shorter values with a 1 byte length prefix.) So we have chosen
   300, allowing 15 levels, such that we can change it in future with a 
meta-data
   only storage change. Regardless of max length of column, all DBs only use as
   much storage as needed (+ size counter).
   
    <!-- SPDX-License-Identifier: Apache-2.0
         https://www.apache.org/licenses/LICENSE-2.0 -->
   
   <!--
   Thank you for contributing!
   
   Please provide above a brief description of the changes made in this pull 
request.
   Write a good git commit message following this guide: 
https://chris.beams.io/posts/git-commit/
   
   Please make sure that your code changes are covered with tests.
   And in case of new features or big changes remember to adjust the 
documentation.
   
   For user-facing UI changes, please attach before/after screenshots (or a 
short
   screen recording) so reviewers can assess the visual impact.
   
   Feel free to ping (in general) for the review if you do not see reaction for 
a few days
   (72 Hours is the minimum reaction time you can expect from volunteers) - we 
sometimes miss notifications.
   
   In case of an existing issue, reference it using one of the following:
   
   * closes: #ISSUE
   * related: #ISSUE
   -->
   
   ---
   
   ##### Was generative AI tooling used to co-author this PR?
   
   <!--
   If generative AI tooling has been used in the process of authoring this PR, 
please
   change below checkbox to `[X]` followed by the name of the tool, uncomment 
the "Generated-by".
   -->
   
   - [ ] Yes (please specify the tool below)
   
   <!--
   Generated-by: [Tool Name] following [the 
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
   -->
   
   ---
   
   * Read the **[Pull Request 
Guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#pull-request-guidelines)**
 for more information. Note: commit author/co-author name and email in commits 
become permanently public when merged.
   * For fundamental code changes, an Airflow Improvement Proposal 
([AIP](https://cwiki.apache.org/confluence/display/AIRFLOW/Airflow+Improvement+Proposals))
 is needed.
   * When adding dependency, check compliance with the [ASF 3rd Party License 
Policy](https://www.apache.org/legal/resolved.html#category-x).
   * For significant user-facing changes create newsfragment: 
`{pr_number}.significant.rst`, in 
[airflow-core/newsfragments](https://github.com/apache/airflow/tree/main/airflow-core/newsfragments).
 You can add this file in a follow-up commit after the PR is created so you 
know the PR number.
   


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