Skip to content

Commit

Permalink
refactor(editor): Stop cloning and serializing full execution data fo…
Browse files Browse the repository at this point in the history
…r `executionFinished` push message (#11703)
  • Loading branch information
netroy authored Nov 14, 2024
1 parent 7bb9002 commit 15ca2c4
Show file tree
Hide file tree
Showing 16 changed files with 273 additions and 478 deletions.
1 change: 1 addition & 0 deletions cypress/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"cypress": "^13.14.2",
"cypress-otp": "^1.0.3",
"cypress-real-events": "^1.13.0",
"flatted": "catalog:",
"lodash": "catalog:",
"nanoid": "catalog:",
"start-server-and-test": "^2.0.8"
Expand Down
4 changes: 2 additions & 2 deletions cypress/support/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Load type definitions that come with Cypress module
/// <reference types="cypress" />

import type { FrontendSettings } from '@n8n/api-types';
import type { FrontendSettings, PushPayload, PushType } from '@n8n/api-types';

Cypress.Keyboard.defaults({
keystrokeDelay: 0,
Expand Down Expand Up @@ -66,7 +66,7 @@ declare global {
droppableSelector: string,
options?: Partial<DragAndDropOptions>,
): void;
push(type: string, data: unknown): void;
push<Type extends PushType>(type: Type, data: PushPayload<Type>): void;
shouldNotHaveConsoleErrors(): void;
window(): Chainable<
AUTWindow & {
Expand Down
74 changes: 35 additions & 39 deletions cypress/utils/executions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { stringify } from 'flatted';
import type { IDataObject, IPinData, ITaskData, ITaskDataConnections } from 'n8n-workflow';
import { nanoid } from 'nanoid';

import { clickExecuteWorkflowButton } from '../composables/workflow';

Expand Down Expand Up @@ -39,56 +39,48 @@ export function createMockNodeExecutionData(
};
}

export function createMockWorkflowExecutionData({
executionId,
function createMockWorkflowExecutionData({
runData,
pinData = {},
lastNodeExecuted,
}: {
executionId: string;
runData: Record<string, ITaskData | ITaskData[]>;
pinData?: IPinData;
lastNodeExecuted: string;
}) {
return {
executionId,
data: {
data: {
startData: {},
resultData: {
runData,
pinData,
lastNodeExecuted,
},
executionData: {
contextData: {},
nodeExecutionStack: [],
metadata: {},
waitingExecution: {},
waitingExecutionSource: {},
},
data: stringify({
startData: {},
resultData: {
runData,
pinData: {},
lastNodeExecuted,
},
mode: 'manual',
startedAt: new Date().toISOString(),
stoppedAt: new Date().toISOString(),
status: 'success',
finished: true,
},
executionData: {
contextData: {},
nodeExecutionStack: [],
metadata: {},
waitingExecution: {},
waitingExecutionSource: {},
},
}),
mode: 'manual',
startedAt: new Date().toISOString(),
stoppedAt: new Date().toISOString(),
status: 'success',
finished: true,
};
}

export function runMockWorkflowExecution({
trigger,
lastNodeExecuted,
runData,
workflowExecutionData,
}: {
trigger?: () => void;
lastNodeExecuted: string;
runData: Array<ReturnType<typeof createMockNodeExecutionData>>;
workflowExecutionData?: ReturnType<typeof createMockWorkflowExecutionData>;
}) {
const executionId = nanoid(8);
const executionId = Math.floor(Math.random() * 1_000_000).toString();

cy.intercept('POST', '/rest/workflows/**/run?**', {
statusCode: 201,
Expand Down Expand Up @@ -125,13 +117,17 @@ export function runMockWorkflowExecution({
resolvedRunData[nodeName] = nodeExecution[nodeName];
});

cy.push(
'executionFinished',
createMockWorkflowExecutionData({
executionId,
lastNodeExecuted,
runData: resolvedRunData,
...workflowExecutionData,
}),
);
cy.intercept('GET', `/rest/executions/${executionId}`, {
statusCode: 200,
body: {
data: createMockWorkflowExecutionData({
lastNodeExecuted,
runData: resolvedRunData,
}),
},
}).as('getExecution');

cy.push('executionFinished', { executionId });

cy.wait('@getExecution');
}
4 changes: 1 addition & 3 deletions packages/@n8n/api-types/src/push/execution.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { IRun, ITaskData, WorkflowExecuteMode } from 'n8n-workflow';
import type { ITaskData, WorkflowExecuteMode } from 'n8n-workflow';

type ExecutionStarted = {
type: 'executionStarted';
Expand All @@ -16,8 +16,6 @@ type ExecutionFinished = {
type: 'executionFinished';
data: {
executionId: string;
data: IRun;
retryOf?: string;
};
};

Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@
"express-rate-limit": "7.2.0",
"fast-glob": "catalog:",
"flat": "5.0.2",
"flatted": "3.2.7",
"flatted": "catalog:",
"formidable": "3.5.1",
"handlebars": "4.7.8",
"helmet": "7.1.0",
Expand Down
46 changes: 5 additions & 41 deletions packages/cli/src/workflow-execute-additional-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,54 +309,18 @@ function hookFunctionsPush(): IWorkflowExecuteHooks {
},
],
workflowExecuteAfter: [
async function (this: WorkflowHooks, fullRunData: IRun): Promise<void> {
const { pushRef, executionId, retryOf } = this;
async function (this: WorkflowHooks): Promise<void> {
const { pushRef, executionId } = this;
if (pushRef === undefined) return;

const { id: workflowId } = this.workflowData;
logger.debug('Executing hook (hookFunctionsPush)', {
executionId,
pushRef,
workflowId,
});
// Push data to session which started the workflow
if (pushRef === undefined) {
return;
}

// Clone the object except the runData. That one is not supposed
// to be send. Because that data got send piece by piece after
// each node which finished executing
// Edit: we now DO send the runData to the UI if mode=manual so that it shows the point of crashes
let pushRunData;
if (fullRunData.mode === 'manual') {
pushRunData = fullRunData;
} else {
pushRunData = {
...fullRunData,
data: {
...fullRunData.data,
resultData: {
...fullRunData.data.resultData,
runData: {},
},
},
};
}

// Push data to editor-ui once workflow finished
logger.debug(`Save execution progress to database for execution ID ${executionId} `, {
executionId,
workflowId,
});
// TODO: Look at this again
pushInstance.send(
'executionFinished',
{
executionId,
data: pushRunData,
retryOf,
},
pushRef,
);
pushInstance.send('executionFinished', { executionId }, pushRef);
},
],
};
Expand Down
2 changes: 1 addition & 1 deletion packages/editor-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"esprima-next": "5.8.4",
"fast-json-stable-stringify": "^2.1.0",
"file-saver": "^2.0.2",
"flatted": "^3.2.4",
"flatted": "catalog:",
"highlight.js": "catalog:frontend",
"humanize-duration": "^3.27.2",
"jsonpath": "^1.1.1",
Expand Down
12 changes: 0 additions & 12 deletions packages/editor-ui/src/Interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,15 +392,10 @@ export interface IExecutionsListResponse {

export interface IExecutionsCurrentSummaryExtended {
id: string;
finished?: boolean;
status: ExecutionStatus;
mode: WorkflowExecuteMode;
retryOf?: string | null;
retrySuccessId?: string | null;
startedAt: Date;
stoppedAt?: Date;
workflowId: string;
workflowName?: string;
}

export interface IExecutionsStopData {
Expand Down Expand Up @@ -839,14 +834,12 @@ export interface IUsedCredential {
}

export interface WorkflowsState {
activeExecutions: IExecutionsCurrentSummaryExtended[];
activeWorkflows: string[];
activeWorkflowExecution: ExecutionSummary | null;
currentWorkflowExecutions: ExecutionSummary[];
activeExecutionId: string | null;
executingNode: string[];
executionWaitingForWebhook: boolean;
finishedExecutionsCount: number;
nodeMetadata: NodeMetadataMap;
subWorkflowExecutionError: Error | null;
usedCredentials: Record<string, IUsedCredential>;
Expand Down Expand Up @@ -1083,11 +1076,6 @@ export interface IVersionsState {
currentVersion: IVersion | undefined;
}

export interface IWorkflowsState {
currentWorkflowExecutions: ExecutionSummary[];
activeWorkflowExecution: ExecutionSummary | null;
finishedExecutionsCount: number;
}
export interface IWorkflowsMap {
[name: string]: IWorkflowDb;
}
Expand Down
Loading

0 comments on commit 15ca2c4

Please sign in to comment.