Răsfoiți Sursa

fix: fetch a page's sub-runs by id, and withdraw a false claim about the database

The children of the runs on a page are asked for by id in one request, which is
what this should have done from the start:

    parentExecutionId in (id, id, ...)

It was fetching them by the time window the page covered and filtering on
triggerType instead, because I had reported that the id query returned nothing
and blamed "in" on a field most documents do not carry.

That was wrong, and the database was never at fault. I had rebuilt the
webserver after adding the multi-id filter and never restarted it, so every
test hit the previous binary, which treated the whole comma-separated string as
one literal value - "exec_A,exec_B" matches no document, while each id on its
own matches one. Restarting made the same request return 2.

Checked properly this time, against the live instance with the upstream client
directly - no webserver, no view, no adapter: "in" works on a sparse field, a
dense field, a collection, a view, with and without the sort the listing uses,
and combined with other filters. The programs are in the finding note.

The window query also had a cap the id query does not: it took at most 200
children across the page's whole time range, so a busy window could silently
miss some. This asks for exactly the children of exactly the parents on screen.

Verified in the browser afterwards: a real 35photo2anime run shows "3 sub-runs"
with ten parent ids in one filter, and the nesting still expands.
fszontagh 1 lună în urmă
părinte
comite
9e167c7f65
1 a modificat fișierele cu 8 adăugiri și 32 ștergeri
  1. 8 32
      webui/src/pages/ExecutionsPage.tsx

+ 8 - 32
webui/src/pages/ExecutionsPage.tsx

@@ -291,42 +291,18 @@ export default function ExecutionsPage() {
     [executions]
   )
 
-  // Asked for by the time window this page covers, not by a list of parent ids.
+  // The children of every run on this page, asked for by id in one request.
   //
-  // The obvious query - parentExecutionId in (id, id, ...) - comes back empty,
-  // although each id on its own matches. The same "in" works on status and on
-  // workflowId, which the listing already scopes itself with; what is different
-  // about parentExecutionId is that most executions do not have the field at
-  // all. Rather than build on an operator that behaves differently on a sparse
-  // field, this asks for the runs that WERE started by another workflow -
-  // triggerType is on every record - within the window the page covers, and
-  // does the grouping here.
-  const childWindow = useMemo(() => {
-    if (topLevel.length === 0) return null
-    let from = Infinity
-    let to = 0
-    for (const row of topLevel) {
-      const started = toMillis(row.startedAt) ?? 0
-      const finished = toMillis(row.finishedAt) || now
-      if (started > 0) from = Math.min(from, started)
-      to = Math.max(to, finished)
-    }
-    return from === Infinity ? null : { from, to }
-    // `now` deliberately absent: a still-running parent would otherwise move
-    // the window every second and refetch the children with it.
-    // eslint-disable-next-line react-hooks/exhaustive-deps
-  }, [topLevel])
+  // Not grouped from whatever the page happens to contain: a child starts after
+  // its parent, so newest-first puts children ABOVE their parent, and a parent
+  // at the top of one page has its children at the bottom of the previous one.
+  const parentIds = useMemo(() => topLevel.map((e) => e.id), [topLevel])
 
   const { data: childRows } = useQuery({
-    queryKey: ['executions', 'children', childWindow?.from, childWindow?.to],
+    queryKey: ['executions', 'children', parentIds],
     queryFn: () =>
-      executionsApi.query({
-        triggerType: ['workflow', 'error-workflow'],
-        startedAfter: childWindow!.from,
-        startedBefore: childWindow!.to,
-        pageSize: 200,
-      }),
-    enabled: !!childWindow,
+      executionsApi.query({ parentExecutionId: parentIds.join(','), pageSize: 200 }),
+    enabled: parentIds.length > 0,
   })
 
   // Grouped by parent, and by their own parent too - a called workflow can call