Browse Source

fix: wire AbortController into regenerateNode for cancellable batch execution

regenerateNode was not creating an AbortController or passing a signal
to _buildExecutionContext, so stopWorkflow() couldn't cancel in-progress
batch iterations. Now creates and stores _abortController on entry and
clears it on all exit paths (early returns, success, and error).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
handoff-20260429-1057
shrimbly 4 months ago
parent
commit
4932995a85
  1. 20
      src/store/workflowStore.ts

20
src/store/workflowStore.ts

@ -1525,7 +1525,9 @@ const workflowStoreImpl: StateCreator<WorkflowStore> = (set, get) => ({
return; return;
} }
set({ isRunning: true, currentNodeIds: [nodeId] }); // Create AbortController so stopWorkflow() can cancel regeneration
const abortController = new AbortController();
set({ isRunning: true, currentNodeIds: [nodeId], _abortController: abortController });
await logger.startSession(); await logger.startSession();
logger.info('node.execution', 'Regenerating node', { logger.info('node.execution', 'Regenerating node', {
@ -1534,7 +1536,7 @@ const workflowStoreImpl: StateCreator<WorkflowStore> = (set, get) => ({
}); });
try { try {
const executionCtx = get()._buildExecutionContext(node); const executionCtx = get()._buildExecutionContext(node, abortController.signal);
const regenOptions = { useStoredFallback: true }; const regenOptions = { useStoredFallback: true };
@ -1559,27 +1561,27 @@ const workflowStoreImpl: StateCreator<WorkflowStore> = (set, get) => ({
await executeSplitGrid(executionCtx); await executeSplitGrid(executionCtx);
} else if (node.type === "videoStitch") { } else if (node.type === "videoStitch") {
await executeVideoStitch(executionCtx); await executeVideoStitch(executionCtx);
set({ isRunning: false, currentNodeIds: [] }); set({ isRunning: false, currentNodeIds: [], _abortController: null });
await logger.endSession(); await logger.endSession();
return; return;
} else if (node.type === "easeCurve") { } else if (node.type === "easeCurve") {
await executeEaseCurve(executionCtx); await executeEaseCurve(executionCtx);
set({ isRunning: false, currentNodeIds: [] }); set({ isRunning: false, currentNodeIds: [], _abortController: null });
await logger.endSession(); await logger.endSession();
return; return;
} else if (node.type === "videoTrim") { } else if (node.type === "videoTrim") {
await executeVideoTrim(executionCtx); await executeVideoTrim(executionCtx);
set({ isRunning: false, currentNodeIds: [] }); set({ isRunning: false, currentNodeIds: [], _abortController: null });
await logger.endSession(); await logger.endSession();
return; return;
} else if (node.type === "videoFrameGrab") { } else if (node.type === "videoFrameGrab") {
await executeVideoFrameGrab(executionCtx); await executeVideoFrameGrab(executionCtx);
set({ isRunning: false, currentNodeIds: [] }); set({ isRunning: false, currentNodeIds: [], _abortController: null });
await logger.endSession(); await logger.endSession();
return; return;
} else if (node.type === "output") { } else if (node.type === "output") {
await executeOutput(executionCtx); await executeOutput(executionCtx);
set({ isRunning: false, currentNodeIds: [] }); set({ isRunning: false, currentNodeIds: [], _abortController: null });
await logger.endSession(); await logger.endSession();
return; return;
} }
@ -1609,7 +1611,7 @@ const workflowStoreImpl: StateCreator<WorkflowStore> = (set, get) => ({
} }
logger.info('node.execution', 'Node regeneration completed successfully', { nodeId }); logger.info('node.execution', 'Node regeneration completed successfully', { nodeId });
set({ isRunning: false, currentNodeIds: [] }); set({ isRunning: false, currentNodeIds: [], _abortController: null });
saveLogSession(); saveLogSession();
await logger.endSession(); await logger.endSession();
@ -1621,7 +1623,7 @@ const workflowStoreImpl: StateCreator<WorkflowStore> = (set, get) => ({
status: "error", status: "error",
error: error instanceof Error ? error.message : "Regeneration failed", error: error instanceof Error ? error.message : "Regeneration failed",
}); });
set({ isRunning: false, currentNodeIds: [] }); set({ isRunning: false, currentNodeIds: [], _abortController: null });
saveLogSession(); saveLogSession();
await logger.endSession(); await logger.endSession();

Loading…
Cancel
Save