Ver código fonte

fix: one name for the execution.waiting event, and let the list react to it

The runner's "execution.waiting" fell through to the generic branch of the
event-to-channel mapping, which does not strip the prefix, so it reached
subscribers as executions.<id>.execution.waiting - while the webhook path
broadcast executions.<id>.waiting for the same event. Every execution-level
event now takes the same rule as started/completed/failed/cancelled, so a
future one cannot repeat this.

The split had a visible consequence. useExecutionListUpdates counts only
started, completed, failed and cancelled as lifecycle events, so pausing for
an approval refreshed nothing: a run that had stopped to ask someone a
question went on showing as running until an unrelated event happened to
invalidate the list. .waiting is now in that set.

Read off the wire rather than inferred: a run that pauses emits .started,
.node_completed and .waiting, and nothing under the doubled name.
fszontagh 1 mês atrás
pai
commit
f90aae3685

+ 9 - 0
src/webserver/api/execution_controller.cpp

@@ -654,6 +654,15 @@ void ExecutionController::receiveExecutionEvent(const httplib::Request& req, htt
             channel = "executions." + execution_id + ".failed";
         } else if (event_type == "execution.cancelled") {
             channel = "executions." + execution_id + ".cancelled";
+        } else if (event_type.starts_with("execution.")) {
+            // Every other execution-level event, by the same rule as the four
+            // above rather than falling to the generic branch at the bottom.
+            //
+            // That branch does not strip the prefix, so "execution.waiting"
+            // went out as "executions.<id>.execution.waiting" while the webhook
+            // path broadcast "executions.<id>.waiting" for the same thing. One
+            // event, two names, and a subscriber could only match one of them.
+            channel = "executions." + execution_id + "." + event_type.substr(10);
         } else if (event_type.starts_with("loop.node.")) {
             // Loop node events: loop.node.running, loop.node.completed, loop.node.failed
             std::string node_status = event_type.substr(10);  // Remove "loop.node." prefix

+ 9 - 2
webui/src/hooks/useExecutionListUpdates.ts

@@ -23,12 +23,19 @@ export function useExecutionListUpdates(options: UseExecutionListUpdatesOptions
   const handleExecutionEvent = useCallback((data: any) => {
     const channel = data._channel || ''
 
-    // Only process lifecycle events that affect the list
+    // Only process lifecycle events that affect the list.
+    //
+    // .waiting belongs here: pausing for an approval changes the row's status,
+    // and without it a run that stopped to ask someone a question went on
+    // showing as running until an unrelated event happened to refresh the list.
+    // It was reaching the client under two different names until the server
+    // settled on this one, which is part of why it was missed.
     const isLifecycleEvent =
       channel.includes('.started') ||
       channel.includes('.completed') ||
       channel.includes('.failed') ||
-      channel.includes('.cancelled')
+      channel.includes('.cancelled') ||
+      channel.includes('.waiting')
 
     if (!isLifecycleEvent) return