bbovenzi commented on code in PR #67846:
URL: https://github.com/apache/airflow/pull/67846#discussion_r3351635359


##########
airflow-core/src/airflow/ui/src/queries/useBulkClearDagRunsDryRun.ts:
##########
@@ -40,43 +40,38 @@ export const useBulkClearDagRunsDryRun = (
   selectedDagRuns: Array<DAGRunResponse>,
   options: Options,
 ) => {
-  const results = useQueries({
-    queries: selectedDagRuns.map((dagRun) => ({
-      enabled,
-      queryFn: () =>
-        DagRunService.clearDagRun({
-          dagId: dagRun.dag_id,
-          dagRunId: dagRun.dag_run_id,
-          requestBody: {
-            dry_run: true,
-            only_failed: options.onlyFailed,
-            only_new: options.onlyNew,
-          },
-        }) as Promise<ClearTaskInstanceCollectionResponse>,
-      queryKey: [
-        useBulkClearDagRunsDryRunKey,
-        dagRun.dag_id,
-        dagRun.dag_run_id,
-        { only_failed: options.onlyFailed, only_new: options.onlyNew },
-      ],
-      refetchOnMount: "always" as const,
-    })),
+  const { data: response, isFetching } = useQuery({
+    enabled: enabled && selectedDagRuns.length > 0,
+    queryFn: () =>
+      DagRunService.clearDagRuns({
+        // ``~`` clears across Dags in a single call; every entry carries its 
own dag_id.
+        dagId: "~",
+        requestBody: {
+          dag_runs: selectedDagRuns.map((dagRun) => ({
+            dag_id: dagRun.dag_id,
+            dag_run_id: dagRun.dag_run_id,
+          })),
+          dry_run: true,
+          only_failed: options.onlyFailed,
+          only_new: options.onlyNew,
+        },
+      }) as Promise<ClearTaskInstanceCollectionResponse>,
+    queryKey: [
+      useBulkClearDagRunsDryRunKey,
+      selectedDagRuns.map((dagRun) => 
`${dagRun.dag_id}.${dagRun.dag_run_id}`).sort(),
+      { only_failed: options.onlyFailed, only_new: options.onlyNew },
+    ],
+    refetchOnMount: "always" as const,
   });
 
-  const isFetching = results.some((result) => result.isFetching);
-  // Each per-run call is scoped to a distinct ``(dag_id, dag_run_id)`` so the
-  // concatenated array can't contain duplicates; the response is also
-  // homogeneous (``only_new=true`` yields ``NewTaskResponse`` placeholders,
-  // ``false`` yields real ``TaskInstanceResponse``), so the cast is safe even
-  // though the OpenAPI type widens to a union.
-  const taskInstances = results.flatMap((result) => 
result.data?.task_instances ?? []);
-  const data: TaskInstanceCollectionResponse =
-    taskInstances.length === 0
-      ? EMPTY
-      : {
-          task_instances: taskInstances as Array<TaskInstanceResponse>,
-          total_entries: taskInstances.length,
-        };
+  // ``only_new=true`` yields ``NewTaskResponse`` placeholders, ``false`` 
yields real
+  // ``TaskInstanceResponse``; the OpenAPI type widens to a union, so narrow 
it here.
+  const data: TaskInstanceCollectionResponse = response
+    ? {
+        task_instances: response.task_instances as Array<TaskInstanceResponse>,
+        total_entries: response.total_entries,
+      }
+    : EMPTY;

Review Comment:
   This is a lot of typecasting that I would like to avoid



##########
airflow-core/src/airflow/ui/src/queries/useBulkClearDagRuns.ts:
##########
@@ -99,64 +84,46 @@ export const useBulkClearDagRuns = ({ deselectKeys, 
onSuccessConfirm }: Props) =
     reset();
     setIsPending(true);
 
-    const settled = await Promise.allSettled(
-      dagRuns.map((dagRun) =>
-        DagRunService.clearDagRun({
-          dagId: dagRun.dag_id,
-          dagRunId: dagRun.dag_run_id,
-          requestBody: {
-            dry_run: false,
-            note: options.note ?? undefined,
-            only_failed: options.onlyFailed,
-            only_new: options.onlyNew,
-          },
-        }).then(() => dagRun),
-      ),
-    );
-
-    const succeeded: Array<DAGRunResponse> = [];
-    const errors: Array<Record<string, unknown>> = [];
-
-    settled.forEach((outcome, index) => {
-      if (outcome.status === "fulfilled") {
-        succeeded.push(outcome.value);
-      } else {
-        const dagRun = dagRuns[index];
-
-        errors.push({
-          error: dagRun
-            ? `${getRowKey(dagRun)}: ${formatError(outcome.reason)}`
-            : formatError(outcome.reason),
-        });
-      }
-    });
+    try {
+      // ``~`` clears runs across Dags atomically in a single request; every 
entry
+      // carries its own dag_id. The whole request succeeds or fails together.
+      await DagRunService.clearDagRuns({
+        dagId: "~",
+        requestBody: {
+          dag_runs: dagRuns.map((dagRun) => ({
+            dag_id: dagRun.dag_id,

Review Comment:
   We shouldn't be handling errors, pending, or even calling the API endpoint 
directly on our own. Use the hook.



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