Nataneljpwd commented on code in PR #64109:
URL: https://github.com/apache/airflow/pull/64109#discussion_r3645485707


##########
airflow-core/src/airflow/models/dagrun.py:
##########
@@ -735,16 +735,33 @@ def get_queued_dag_runs_to_set_running(cls, session: 
Session) -> ScalarResult[Da
             .subquery()
         )
 
-        query = (
-            select(cls)
-            .where(cls.state == DagRunState.QUEUED)
+        available_dagruns_rn = (
+            select(
+                DagRun.dag_id,
+                DagRun.id,
+                running_drs.c.num_running,
+                func.row_number()
+                .over(
+                    partition_by=[DagRun.dag_id, DagRun.backfill_id],
+                    order_by=[
+                        nulls_first(cast("ColumnElement[Any]", 
BackfillDagRun.sort_ordinal), session=session),
+                        nulls_first(
+                            cast("ColumnElement[Any]", 
cls.last_scheduling_decision), session=session
+                        ),
+                        nulls_first(running_drs.c.num_running, 
session=session),
+                        DagRun.run_after,
+                    ],
+                )
+                .label("rn"),
+            )
+            .where(DagRun.state == DagRunState.QUEUED)
             .join(
-                DagModel,
+                running_drs,
                 and_(
-                    DagModel.dag_id == cls.dag_id,
-                    DagModel.is_paused == false(),
-                    DagModel.is_stale == false(),
+                    running_drs.c.dag_id == DagRun.dag_id,
+                    running_drs.c.backfill_id == DagRun.backfill_id,

Review Comment:
   Not here, in the next query part, if it had run id then all dags with no 
runs would be ignored, this step produces a result that looks like so:
   -----------------------------------------------------------
   Dag id | Run id | num currently running | serial count of DR (later used for 
filtering) |
   
   Where the serial count is given and ordered by the dagrun prioritization 
(the 3 order bys in the row number func)
   
   Later in the next query part I select the amount of available dagrun slots 
for given dag (max active runs - current run count) by the row number (where 
the serially increasing number is less than the available slots)
   
   And because there are row locks for the dagrun, only those dagruns are 
available to run and it selects exactly max dagruns per loop to schedule 
dagruns (or less if there aren't any) which can be scheduled by filtering those 
which cannot move to running in the SQL query
   
   I will give an example:
   
   If we have dags A, B and C where A has aax active runs of 1, B has 1 and C 
has 3, the current implementation selects the first 5 (for this example) 
dagruns ordered by their respective "priority"
   Assume we have the following  situations, there is already 2 DR running for 
C and many more in queued
   The queued DR select looks like so:
   CCCCCCCAAABBACCCAB
   The current implementation will select 5 of the C DR, schedule 1 and go on, 
the next iteration same thing happens and 1 DR from a Is set to running
   The implementation proposed changes the result of the query by only 
selecting DRs which can be set to running, hence the DR queue will look like so 
(and the query result as well)
   CAB
   And nothing else gets returned 
   This is a simplified example, with more DRs this issue cam become worse and 
DRs are not moved to running and stay queued for a long time
   
   If something isn't clear let me know and I'll try to clarify 
   Thank you



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