mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix(core): Fix issue with not displayed child workflow executions (#3867)
This commit is contained in:
parent
d4b4e234a6
commit
f782bcd52d
|
@ -31,6 +31,7 @@ import {
|
||||||
IWorkflowExecuteAdditionalData,
|
IWorkflowExecuteAdditionalData,
|
||||||
IWorkflowExecuteHooks,
|
IWorkflowExecuteHooks,
|
||||||
IWorkflowHooksOptionalParameters,
|
IWorkflowHooksOptionalParameters,
|
||||||
|
IWorkflowSettings,
|
||||||
LoggerProxy as Logger,
|
LoggerProxy as Logger,
|
||||||
Workflow,
|
Workflow,
|
||||||
WorkflowExecuteMode,
|
WorkflowExecuteMode,
|
||||||
|
@ -810,6 +811,8 @@ export async function getRunData(
|
||||||
export async function getWorkflowData(
|
export async function getWorkflowData(
|
||||||
workflowInfo: IExecuteWorkflowInfo,
|
workflowInfo: IExecuteWorkflowInfo,
|
||||||
userId: string,
|
userId: string,
|
||||||
|
parentWorkflowId?: string,
|
||||||
|
parentWorkflowSettings?: IWorkflowSettings,
|
||||||
): Promise<IWorkflowBase> {
|
): Promise<IWorkflowBase> {
|
||||||
if (workflowInfo.id === undefined && workflowInfo.code === undefined) {
|
if (workflowInfo.id === undefined && workflowInfo.code === undefined) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
@ -847,6 +850,14 @@ export async function getWorkflowData(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
workflowData = workflowInfo.code;
|
workflowData = workflowInfo.code;
|
||||||
|
if (workflowData) {
|
||||||
|
if (!workflowData.id) {
|
||||||
|
workflowData.id = parentWorkflowId;
|
||||||
|
}
|
||||||
|
if (!workflowData.settings) {
|
||||||
|
workflowData.settings = parentWorkflowSettings;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return workflowData!;
|
return workflowData!;
|
||||||
|
@ -864,10 +875,14 @@ export async function getWorkflowData(
|
||||||
export async function executeWorkflow(
|
export async function executeWorkflow(
|
||||||
workflowInfo: IExecuteWorkflowInfo,
|
workflowInfo: IExecuteWorkflowInfo,
|
||||||
additionalData: IWorkflowExecuteAdditionalData,
|
additionalData: IWorkflowExecuteAdditionalData,
|
||||||
inputData?: INodeExecutionData[],
|
options?: {
|
||||||
parentExecutionId?: string,
|
parentWorkflowId?: string;
|
||||||
loadedWorkflowData?: IWorkflowBase,
|
inputData?: INodeExecutionData[];
|
||||||
loadedRunData?: IWorkflowExecutionDataProcess,
|
parentExecutionId?: string;
|
||||||
|
loadedWorkflowData?: IWorkflowBase;
|
||||||
|
loadedRunData?: IWorkflowExecutionDataProcess;
|
||||||
|
parentWorkflowSettings?: IWorkflowSettings;
|
||||||
|
},
|
||||||
): Promise<Array<INodeExecutionData[] | null> | IWorkflowExecuteProcess> {
|
): Promise<Array<INodeExecutionData[] | null> | IWorkflowExecuteProcess> {
|
||||||
const externalHooks = ExternalHooks();
|
const externalHooks = ExternalHooks();
|
||||||
await externalHooks.init();
|
await externalHooks.init();
|
||||||
|
@ -875,30 +890,38 @@ export async function executeWorkflow(
|
||||||
const nodeTypes = NodeTypes();
|
const nodeTypes = NodeTypes();
|
||||||
|
|
||||||
const workflowData =
|
const workflowData =
|
||||||
loadedWorkflowData ?? (await getWorkflowData(workflowInfo, additionalData.userId));
|
options?.loadedWorkflowData ??
|
||||||
|
(await getWorkflowData(
|
||||||
|
workflowInfo,
|
||||||
|
additionalData.userId,
|
||||||
|
options?.parentWorkflowId,
|
||||||
|
options?.parentWorkflowSettings,
|
||||||
|
));
|
||||||
|
|
||||||
const workflowName = workflowData ? workflowData.name : undefined;
|
const workflowName = workflowData ? workflowData.name : undefined;
|
||||||
const workflow = new Workflow({
|
const workflow = new Workflow({
|
||||||
id: workflowInfo.id,
|
id: workflowData.id?.toString(),
|
||||||
name: workflowName,
|
name: workflowName,
|
||||||
nodes: workflowData.nodes,
|
nodes: workflowData.nodes,
|
||||||
connections: workflowData.connections,
|
connections: workflowData.connections,
|
||||||
active: workflowData.active,
|
active: workflowData.active,
|
||||||
nodeTypes,
|
nodeTypes,
|
||||||
staticData: workflowData.staticData,
|
staticData: workflowData.staticData,
|
||||||
|
settings: workflowData.settings,
|
||||||
});
|
});
|
||||||
|
|
||||||
const runData =
|
const runData =
|
||||||
loadedRunData ?? (await getRunData(workflowData, additionalData.userId, inputData));
|
options?.loadedRunData ??
|
||||||
|
(await getRunData(workflowData, additionalData.userId, options?.inputData));
|
||||||
|
|
||||||
let executionId;
|
let executionId;
|
||||||
|
|
||||||
if (parentExecutionId !== undefined) {
|
if (options?.parentExecutionId !== undefined) {
|
||||||
executionId = parentExecutionId;
|
executionId = options?.parentExecutionId;
|
||||||
} else {
|
} else {
|
||||||
executionId =
|
executionId =
|
||||||
parentExecutionId !== undefined
|
options?.parentExecutionId !== undefined
|
||||||
? parentExecutionId
|
? options?.parentExecutionId
|
||||||
: await ActiveExecutions.getInstance().add(runData);
|
: await ActiveExecutions.getInstance().add(runData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -946,7 +969,7 @@ export async function executeWorkflow(
|
||||||
runData.executionMode,
|
runData.executionMode,
|
||||||
runExecutionData,
|
runExecutionData,
|
||||||
);
|
);
|
||||||
if (parentExecutionId !== undefined) {
|
if (options?.parentExecutionId !== undefined) {
|
||||||
// Must be changed to become typed
|
// Must be changed to become typed
|
||||||
return {
|
return {
|
||||||
startedAt: new Date(),
|
startedAt: new Date(),
|
||||||
|
|
|
@ -247,6 +247,7 @@ export class WorkflowRunner {
|
||||||
active: data.workflowData.active,
|
active: data.workflowData.active,
|
||||||
nodeTypes,
|
nodeTypes,
|
||||||
staticData: data.workflowData.staticData,
|
staticData: data.workflowData.staticData,
|
||||||
|
settings: data.workflowData.settings,
|
||||||
});
|
});
|
||||||
const additionalData = await WorkflowExecuteAdditionalData.getBase(
|
const additionalData = await WorkflowExecuteAdditionalData.getBase(
|
||||||
data.userId,
|
data.userId,
|
||||||
|
|
|
@ -23,6 +23,7 @@ import {
|
||||||
ITaskData,
|
ITaskData,
|
||||||
IWorkflowExecuteAdditionalData,
|
IWorkflowExecuteAdditionalData,
|
||||||
IWorkflowExecuteHooks,
|
IWorkflowExecuteHooks,
|
||||||
|
IWorkflowSettings,
|
||||||
LoggerProxy,
|
LoggerProxy,
|
||||||
Workflow,
|
Workflow,
|
||||||
WorkflowExecuteMode,
|
WorkflowExecuteMode,
|
||||||
|
@ -183,6 +184,12 @@ export class WorkflowRunnerProcess {
|
||||||
if (Object.keys(node.credentials === undefined ? {} : node.credentials).length > 0) {
|
if (Object.keys(node.credentials === undefined ? {} : node.credentials).length > 0) {
|
||||||
shouldInitializaDb = true;
|
shouldInitializaDb = true;
|
||||||
}
|
}
|
||||||
|
if (node.type === 'n8n-nodes-base.executeWorkflow') {
|
||||||
|
// With UM, child workflows from arbitrary JSON
|
||||||
|
// Should be persisted by the child process,
|
||||||
|
// so DB needs to be initialized
|
||||||
|
shouldInitializaDb = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// This code has been split into 4 ifs just to make it easier to understand
|
// This code has been split into 4 ifs just to make it easier to understand
|
||||||
|
@ -271,16 +278,22 @@ export class WorkflowRunnerProcess {
|
||||||
additionalData.executeWorkflow = async (
|
additionalData.executeWorkflow = async (
|
||||||
workflowInfo: IExecuteWorkflowInfo,
|
workflowInfo: IExecuteWorkflowInfo,
|
||||||
additionalData: IWorkflowExecuteAdditionalData,
|
additionalData: IWorkflowExecuteAdditionalData,
|
||||||
inputData?: INodeExecutionData[] | undefined,
|
options?: {
|
||||||
|
parentWorkflowId?: string;
|
||||||
|
inputData?: INodeExecutionData[];
|
||||||
|
parentWorkflowSettings?: IWorkflowSettings;
|
||||||
|
},
|
||||||
): Promise<Array<INodeExecutionData[] | null> | IRun> => {
|
): Promise<Array<INodeExecutionData[] | null> | IRun> => {
|
||||||
const workflowData = await WorkflowExecuteAdditionalData.getWorkflowData(
|
const workflowData = await WorkflowExecuteAdditionalData.getWorkflowData(
|
||||||
workflowInfo,
|
workflowInfo,
|
||||||
userId,
|
userId,
|
||||||
|
options?.parentWorkflowId,
|
||||||
|
options?.parentWorkflowSettings,
|
||||||
);
|
);
|
||||||
const runData = await WorkflowExecuteAdditionalData.getRunData(
|
const runData = await WorkflowExecuteAdditionalData.getRunData(
|
||||||
workflowData,
|
workflowData,
|
||||||
additionalData.userId,
|
additionalData.userId,
|
||||||
inputData,
|
options?.inputData,
|
||||||
);
|
);
|
||||||
await sendToParentProcess('startExecution', { runData });
|
await sendToParentProcess('startExecution', { runData });
|
||||||
const executionId: string = await new Promise((resolve) => {
|
const executionId: string = await new Promise((resolve) => {
|
||||||
|
@ -293,10 +306,14 @@ export class WorkflowRunnerProcess {
|
||||||
const executeWorkflowFunctionOutput = (await executeWorkflowFunction(
|
const executeWorkflowFunctionOutput = (await executeWorkflowFunction(
|
||||||
workflowInfo,
|
workflowInfo,
|
||||||
additionalData,
|
additionalData,
|
||||||
inputData,
|
{
|
||||||
executionId,
|
parentWorkflowId: options?.parentWorkflowId,
|
||||||
workflowData,
|
inputData: options?.inputData,
|
||||||
runData,
|
parentExecutionId: executionId,
|
||||||
|
loadedWorkflowData: workflowData,
|
||||||
|
loadedRunData: runData,
|
||||||
|
parentWorkflowSettings: options?.parentWorkflowSettings,
|
||||||
|
},
|
||||||
)) as { workflowExecute: WorkflowExecute; workflow: Workflow } as IWorkflowExecuteProcess;
|
)) as { workflowExecute: WorkflowExecute; workflow: Workflow } as IWorkflowExecuteProcess;
|
||||||
const { workflowExecute } = executeWorkflowFunctionOutput;
|
const { workflowExecute } = executeWorkflowFunctionOutput;
|
||||||
this.childExecutions[executionId] = executeWorkflowFunctionOutput;
|
this.childExecutions[executionId] = executeWorkflowFunctionOutput;
|
||||||
|
|
|
@ -2199,7 +2199,11 @@ export function getExecuteFunctions(
|
||||||
inputData?: INodeExecutionData[],
|
inputData?: INodeExecutionData[],
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
return additionalData
|
return additionalData
|
||||||
.executeWorkflow(workflowInfo, additionalData, inputData)
|
.executeWorkflow(workflowInfo, additionalData, {
|
||||||
|
parentWorkflowId: workflow.id?.toString(),
|
||||||
|
inputData,
|
||||||
|
parentWorkflowSettings: workflow.settings,
|
||||||
|
})
|
||||||
.then(async (result) =>
|
.then(async (result) =>
|
||||||
BinaryDataManager.getInstance().duplicateBinaryData(
|
BinaryDataManager.getInstance().duplicateBinaryData(
|
||||||
result,
|
result,
|
||||||
|
|
|
@ -1437,10 +1437,14 @@ export interface IWorkflowExecuteAdditionalData {
|
||||||
executeWorkflow: (
|
executeWorkflow: (
|
||||||
workflowInfo: IExecuteWorkflowInfo,
|
workflowInfo: IExecuteWorkflowInfo,
|
||||||
additionalData: IWorkflowExecuteAdditionalData,
|
additionalData: IWorkflowExecuteAdditionalData,
|
||||||
inputData?: INodeExecutionData[],
|
options?: {
|
||||||
parentExecutionId?: string,
|
parentWorkflowId?: string;
|
||||||
loadedWorkflowData?: IWorkflowBase,
|
inputData?: INodeExecutionData[];
|
||||||
loadedRunData?: any,
|
parentExecutionId?: string;
|
||||||
|
loadedWorkflowData?: IWorkflowBase;
|
||||||
|
loadedRunData?: any;
|
||||||
|
parentWorkflowSettings?: IWorkflowSettings;
|
||||||
|
},
|
||||||
) => Promise<any>;
|
) => Promise<any>;
|
||||||
// hooks?: IWorkflowExecuteHooks;
|
// hooks?: IWorkflowExecuteHooks;
|
||||||
executionId?: string;
|
executionId?: string;
|
||||||
|
|
|
@ -217,7 +217,7 @@ export function getExecuteFunctions(
|
||||||
workflowInfo: IExecuteWorkflowInfo,
|
workflowInfo: IExecuteWorkflowInfo,
|
||||||
inputData?: INodeExecutionData[],
|
inputData?: INodeExecutionData[],
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
return additionalData.executeWorkflow(workflowInfo, additionalData, inputData);
|
return additionalData.executeWorkflow(workflowInfo, additionalData, { inputData });
|
||||||
},
|
},
|
||||||
getContext(type: string): IContextObject {
|
getContext(type: string): IContextObject {
|
||||||
return NodeHelpers.getContext(runExecutionData, type, node);
|
return NodeHelpers.getContext(runExecutionData, type, node);
|
||||||
|
|
Loading…
Reference in a new issue