seanmuth commented on code in PR #73692:
URL: https://github.com/apache/airflow/pull/73692#discussion_r4106448874


##########
airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml:
##########
@@ -13511,6 +13514,7 @@ components:
       - timezone
       - last_parsed
       - default_args
+      - exceeds_max_active_runs

Review Comment:
   I'd argue the column should persist (it's NOT NULL in the db) and the 
expected use case pattern is for checking whether a given Dag is at run 
capacity before triggering another run — requiring client-side logic to parse 
an `if exists(exceeded_max_active_runs)` feels annoying compared to the 
client-side `if exceeded_max_active_runs then ...` (agreed on the API field 
naming change, more in the response comment below).
   
   ---
   Drafted-by: Claude Sonnet 5; reviewed by @seanmuth before posting



##########
airflow-core/src/airflow/dag_processing/collection.py:
##########
@@ -176,9 +176,19 @@ def calculate(cls, dag: LazyDeserializedDAG, *, session: 
Session) -> Self:
 
         :param dags: dict of dags to query
         """
-        # Skip these queries entirely if no Dags can be scheduled to save time.
+        active_run_counts = DagRun.active_runs_of_dags(

Review Comment:
   If a Dag doesn't define `max_active_runs` it will still inherit the 
deployment's config for `[core] max_active_runs_per_dag`, so that value will 
never be `NULL`.
   
   On the N+1: you're right, and it turns out this was already an N+1 for 
schedulable Dags before this PR — `update_dags()` calls `_RunInfo.calculate()` 
once per Dag inside a loop over every Dag in the current parse-result update, 
and that function was calling `DagRun.active_runs_of_dags()` with a 
single-element `dag_ids` list each time, even though that function already 
accepts a list and batches internally. My change to the non-schedulable path 
was just extending that existing per-Dag-query pattern to more Dags, not 
introducing a new shape of the problem. Fixed by hoisting the call out of the 
loop into one batched call across every Dag in the update, and passing each 
Dag's precomputed count into `_RunInfo.calculate()` — pushed in the latest 
commit.
   
   ---
   Drafted-by: Claude Sonnet 5; reviewed by @seanmuth before posting



##########
airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts:
##########
@@ -3285,6 +3285,10 @@ export const $DAGDetailsResponse = {
             title: 'Active Runs Count',
             default: 0
         },
+        exceeds_max_active_runs: {
+            type: 'boolean',
+            title: 'Exceeds Max Active Runs'

Review Comment:
   On naming: agreed "exceeds" is imprecise — it'll be `True` when a Dag is 
sitting exactly *at* capacity too, not just over it, and that's actually the 
source-level naming, not something introduced by exposing it. Renamed the 
exposed field to `is_at_max_active_runs`, using the existing 
`DAG_ALIAS_MAPPING` mechanism so the API name doesn't have to match the 
internal one. Didn't rename `exceeds_max_non_backfill` itself here — that's a 
persisted column, and while a rename migration would be pretty trivial, it felt 
like a separate, deliberate change rather than something to fold into this PR.
   
   Also — while chasing the "at vs exceeds" semantics, found something worth 
flagging separately: `max_active_runs <= 0` behaves inconsistently across the 
codebase (the SQL promotion gate treats both `0` and `-1` as "never 
satisfiable" → Dag Runs queue up forever with no error, while 
`exceeds_max_non_backfill`'s own comparison evaluates permanently `True` for 
both, even with zero active runs). Not something this PR touches — filed as a 
finding on #73686 for visibility.
   
   ---
   Drafted-by: Claude Sonnet 5; reviewed by @seanmuth before posting



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