This is an automated email from the ASF dual-hosted git repository.

bbovenzi pushed a commit to branch v3-4-test
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/v3-4-test by this push:
     new 65515bde8e0 [v3-4-test] UI: Fix slow pending Dag run checks on large 
databases (#75674) (#75799)
65515bde8e0 is described below

commit 65515bde8e0b7efa471ca820c6e84e2a29edf258
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Tue Oct 27 17:03:34 2026 +0000

    [v3-4-test] UI: Fix slow pending Dag run checks on large databases (#75674) 
(#75799)
    
    (cherry picked from commit 91ca0ac42c80deb9798dbfd637e7702d2f8a2c47)
    
    Co-authored-by: Yuseok Jo <[email protected]>
---
 .../src/airflow/ui/src/utils/query.test.ts         | 50 ++++++++++++++++++++++
 airflow-core/src/airflow/ui/src/utils/query.ts     |  7 +--
 2 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/airflow-core/src/airflow/ui/src/utils/query.test.ts 
b/airflow-core/src/airflow/ui/src/utils/query.test.ts
new file mode 100644
index 00000000000..ba72d50aa52
--- /dev/null
+++ b/airflow-core/src/airflow/ui/src/utils/query.test.ts
@@ -0,0 +1,50 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { renderHook, waitFor } from "@testing-library/react";
+import { http, HttpResponse } from "msw";
+import { expect, it } from "vitest";
+
+import { server } from "src/mocks/server";
+import { Wrapper } from "src/utils/Wrapper";
+import { useAutoRefresh } from "src/utils/query";
+
+it("refreshes when pending runs exist without fetching any of them", async () 
=> {
+  const autoRefreshInterval = 5;
+  const pendingRuns = [{ dag_run_id: "running_run" }, { dag_run_id: 
"queued_run" }];
+  const requestedLimits: Array<string | null> = [];
+
+  server.use(
+    http.get("/ui/config", () => HttpResponse.json({ auto_refresh_interval: 
autoRefreshInterval })),
+    http.get("/api/v2/dags/~/dagRuns", ({ request }) => {
+      const limit = new URL(request.url).searchParams.get("limit");
+
+      requestedLimits.push(limit);
+
+      return HttpResponse.json({
+        dag_runs: pendingRuns.slice(0, Number(limit)),
+        total_entries: pendingRuns.length,
+      });
+    }),
+  );
+
+  const { result } = renderHook(() => useAutoRefresh({ checkPendingRuns: true 
}), { wrapper: Wrapper });
+
+  await waitFor(() => expect(result.current).toBe(autoRefreshInterval * 1000));
+  expect(new Set(requestedLimits)).toEqual(new Set(["0"]));
+});
diff --git a/airflow-core/src/airflow/ui/src/utils/query.ts 
b/airflow-core/src/airflow/ui/src/utils/query.ts
index f364fcab0de..4dced5b1cd5 100644
--- a/airflow-core/src/airflow/ui/src/utils/query.ts
+++ b/airflow-core/src/airflow/ui/src/utils/query.ts
@@ -52,7 +52,8 @@ export const useAutoRefresh = ({
   const { data: dagRunData } = useDagRunServiceGetDagRuns(
     {
       dagId: dagId ?? "~",
-      limit: 1,
+      // Only the count is needed. Fetching a row can make Postgres scan 
dag_run from its oldest run.
+      limit: 0,
       state: ["running", "queued"],
     },
     undefined,
@@ -61,13 +62,13 @@ export const useAutoRefresh = ({
       enabled: checkPendingRuns,
       refetchInterval: (query) =>
         autoRefreshInterval !== undefined &&
-        ((query.state.data?.dag_runs ?? []).length > 0
+        ((query.state.data?.total_entries ?? 0) > 0
           ? autoRefreshInterval * 1000
           : autoRefreshInterval * 10 * 1000),
     },
   );
 
-  const pendingRuns = !checkPendingRuns || (dagRunData?.dag_runs ?? []).length 
>= 1;
+  const pendingRuns = !checkPendingRuns || (dagRunData?.total_entries ?? 0) > 
0;
 
   const paused = Boolean(dagId) && dag?.is_paused;
 

Reply via email to