feat(core): Parent workflows should wait for sub-workflows to finish (#11985)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2024-12-06 12:20:34 +01:00
committed by GitHub
parent 956b11a560
commit 60b3dccf93
18 changed files with 257 additions and 70 deletions

View File

@@ -22,7 +22,7 @@ import type {
ISourceData,
AiEvent,
} from 'n8n-workflow';
import { ApplicationError, NodeHelpers, WorkflowDataProxy } from 'n8n-workflow';
import { ApplicationError, NodeHelpers, WAIT_INDEFINITELY, WorkflowDataProxy } from 'n8n-workflow';
import { Container } from 'typedi';
import { BinaryDataService } from '@/BinaryData/BinaryData.service';
@@ -97,6 +97,13 @@ export class BaseExecuteContext extends NodeExecutionContext {
);
}
async putExecutionToWait(waitTill: Date): Promise<void> {
this.runExecutionData.waitTill = waitTill;
if (this.additionalData.setExecutionStatus) {
this.additionalData.setExecutionStatus('waiting');
}
}
async executeWorkflow(
workflowInfo: IExecuteWorkflowInfo,
inputData?: INodeExecutionData[],
@@ -106,23 +113,28 @@ export class BaseExecuteContext extends NodeExecutionContext {
parentExecution?: RelatedExecution;
},
): Promise<ExecuteWorkflowData> {
return await this.additionalData
.executeWorkflow(workflowInfo, this.additionalData, {
...options,
parentWorkflowId: this.workflow.id?.toString(),
inputData,
parentWorkflowSettings: this.workflow.settings,
node: this.node,
parentCallbackManager,
})
.then(async (result) => {
const data = await this.binaryDataService.duplicateBinaryData(
this.workflow.id,
this.additionalData.executionId!,
result.data,
);
return { ...result, data };
});
const result = await this.additionalData.executeWorkflow(workflowInfo, this.additionalData, {
...options,
parentWorkflowId: this.workflow.id,
inputData,
parentWorkflowSettings: this.workflow.settings,
node: this.node,
parentCallbackManager,
});
// If a sub-workflow execution goes into the waiting state
if (result.waitTill) {
// then put the parent workflow execution also into the waiting state,
// but do not use the sub-workflow `waitTill` to avoid WaitTracker resuming the parent execution at the same time as the sub-workflow
await this.putExecutionToWait(WAIT_INDEFINITELY);
}
const data = await this.binaryDataService.duplicateBinaryData(
this.workflow.id,
this.additionalData.executionId!,
result.data,
);
return { ...result, data };
}
getNodeInputs(): INodeInputConfiguration[] {