feat(core): Lazy-load nodes and credentials to reduce baseline memory usage (#4577)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2022-11-23 16:20:28 +01:00
committed by GitHub
parent f63cd3b89e
commit b6c57e19fc
71 changed files with 1102 additions and 1279 deletions

View File

@@ -11,15 +11,11 @@ import { BinaryDataManager, IProcessMessage, UserSettings, WorkflowExecute } fro
import {
ErrorReporterProxy as ErrorReporter,
ExecutionError,
ICredentialType,
ICredentialTypeData,
IDataObject,
IExecuteResponsePromiseData,
IExecuteWorkflowInfo,
ILogger,
INodeExecutionData,
INodeType,
INodeTypeData,
IRun,
ITaskData,
IWorkflowExecuteAdditionalData,
@@ -39,6 +35,7 @@ import { ExternalHooks } from '@/ExternalHooks';
import * as GenericHelpers from '@/GenericHelpers';
import { IWorkflowExecuteProcess, IWorkflowExecutionDataProcessWithExecution } from '@/Interfaces';
import { NodeTypes } from '@/NodeTypes';
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
import * as WebhookHelpers from '@/WebhookHelpers';
import * as WorkflowHelpers from '@/WorkflowHelpers';
import * as WorkflowExecuteAdditionalData from '@/WorkflowExecuteAdditionalData';
@@ -46,12 +43,11 @@ import { getLogger } from '@/Logger';
import config from '@/config';
import { InternalHooksManager } from '@/InternalHooksManager';
import { loadClassInIsolation } from '@/CommunityNodes/helpers';
import { generateFailedExecutionFromError } from '@/WorkflowHelpers';
import { initErrorHandling } from '@/ErrorReporting';
import { PermissionChecker } from '@/UserManagement/PermissionChecker';
export class WorkflowRunnerProcess {
class WorkflowRunnerProcess {
data: IWorkflowExecutionDataProcessWithExecution | undefined;
logger: ILogger;
@@ -99,54 +95,15 @@ export class WorkflowRunnerProcess {
this.startedAt = new Date();
// Load the required nodes
const nodeTypesData: INodeTypeData = {};
// eslint-disable-next-line no-restricted-syntax
for (const nodeTypeName of Object.keys(this.data.nodeTypeData)) {
let tempNode: INodeType;
const { className, sourcePath } = this.data.nodeTypeData[nodeTypeName];
const loadNodesAndCredentials = LoadNodesAndCredentials();
await loadNodesAndCredentials.init();
try {
tempNode = loadClassInIsolation(sourcePath, className);
} catch (error) {
throw new Error(`Error loading node "${nodeTypeName}" from: "${sourcePath}"`);
}
nodeTypesData[nodeTypeName] = {
type: tempNode,
sourcePath,
};
}
const nodeTypes = NodeTypes();
await nodeTypes.init(nodeTypesData);
// Load the required credentials
const credentialsTypeData: ICredentialTypeData = {};
// eslint-disable-next-line no-restricted-syntax
for (const credentialTypeName of Object.keys(this.data.credentialsTypeData)) {
let tempCredential: ICredentialType;
const { className, sourcePath } = this.data.credentialsTypeData[credentialTypeName];
try {
tempCredential = loadClassInIsolation(sourcePath, className);
} catch (error) {
throw new Error(`Error loading credential "${credentialTypeName}" from: "${sourcePath}"`);
}
credentialsTypeData[credentialTypeName] = {
type: tempCredential,
sourcePath,
};
}
// Init credential types the workflow uses (is needed to apply default values to credentials)
const credentialTypes = CredentialTypes();
await credentialTypes.init(credentialsTypeData);
const nodeTypes = NodeTypes(loadNodesAndCredentials);
const credentialTypes = CredentialTypes(loadNodesAndCredentials);
// Load the credentials overwrites if any exist
const credentialsOverwrites = CredentialsOverwrites();
await credentialsOverwrites.init(inputData.credentialsOverwrite);
const credentialsOverwrites = CredentialsOverwrites(credentialTypes);
await credentialsOverwrites.init();
// Load all external hooks
const externalHooks = ExternalHooks();