refactor(core): Use an IoC container to manage singleton classes [Part-1] (no-changelog) (#5509)

* add typedi

* convert ActiveWorkflowRunner into an injectable service

* convert ExternalHooks into an injectable service

* convert InternalHooks into an injectable service

* convert LoadNodesAndCredentials into an injectable service

* convert NodeTypes and CredentialTypes into an injectable service

* convert ActiveExecutions into an injectable service

* convert WaitTracker into an injectable service

* convert Push into an injectable service

* convert ActiveWebhooks and  TestWebhooks into an injectable services

* handle circular references, and log errors when a circular dependency is found
This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2023-02-21 19:21:56 +01:00
committed by GitHub
parent aca94bb995
commit 52f740b9e8
79 changed files with 594 additions and 634 deletions

View File

@@ -1,3 +1,4 @@
import { Container } from 'typedi';
import { validate as jsonSchemaValidate } from 'jsonschema';
import type { INode, IPinData, JsonObject } from 'n8n-workflow';
import { NodeApiError, jsonParse, LoggerProxy, Workflow } from 'n8n-workflow';
@@ -5,9 +6,8 @@ import type { FindOptionsSelect, FindOptionsWhere, UpdateResult } from 'typeorm'
import { In } from 'typeorm';
import pick from 'lodash.pick';
import { v4 as uuid } from 'uuid';
import * as ActiveWorkflowRunner from '@/ActiveWorkflowRunner';
import { ActiveWorkflowRunner } from '@/ActiveWorkflowRunner';
import * as Db from '@/Db';
import { InternalHooksManager } from '@/InternalHooksManager';
import * as ResponseHelper from '@/ResponseHelper';
import * as WorkflowHelpers from '@/WorkflowHelpers';
import config from '@/config';
@@ -22,10 +22,11 @@ import type { IWorkflowDb, IWorkflowExecutionDataProcess } from '@/Interfaces';
import { NodeTypes } from '@/NodeTypes';
import { WorkflowRunner } from '@/WorkflowRunner';
import * as WorkflowExecuteAdditionalData from '@/WorkflowExecuteAdditionalData';
import * as TestWebhooks from '@/TestWebhooks';
import { TestWebhooks } from '@/TestWebhooks';
import { getSharedWorkflowIds } from '@/WorkflowHelpers';
import { isSharingEnabled, whereClause } from '@/UserManagement/UserManagementHelper';
import type { WorkflowForList } from '@/workflows/workflows.types';
import { InternalHooks } from '@/InternalHooks';
export type IGetWorkflowsQueryFilter = Pick<
FindOptionsWhere<WorkflowEntity>,
@@ -91,7 +92,7 @@ export class WorkflowsService {
nodes: workflow.nodes,
connections: workflow.connections,
active: workflow.active,
nodeTypes: NodeTypes(),
nodeTypes: Container.get(NodeTypes),
}).getParentNodes(startNodeName);
let checkNodeName = '';
@@ -236,12 +237,12 @@ export class WorkflowsService {
WorkflowHelpers.addNodeIds(workflow);
await ExternalHooks().run('workflow.update', [workflow]);
await Container.get(ExternalHooks).run('workflow.update', [workflow]);
if (shared.workflow.active) {
// When workflow gets saved always remove it as the triggers could have been
// changed and so the changes would not take effect
await ActiveWorkflowRunner.getInstance().remove(workflowId);
await Container.get(ActiveWorkflowRunner).remove(workflowId);
}
if (workflow.settings) {
@@ -319,14 +320,14 @@ export class WorkflowsService {
});
}
await ExternalHooks().run('workflow.afterUpdate', [updatedWorkflow]);
void InternalHooksManager.getInstance().onWorkflowSaved(user, updatedWorkflow, false);
await Container.get(ExternalHooks).run('workflow.afterUpdate', [updatedWorkflow]);
void Container.get(InternalHooks).onWorkflowSaved(user, updatedWorkflow, false);
if (updatedWorkflow.active) {
// When the workflow is supposed to be active add it again
try {
await ExternalHooks().run('workflow.activate', [updatedWorkflow]);
await ActiveWorkflowRunner.getInstance().add(
await Container.get(ExternalHooks).run('workflow.activate', [updatedWorkflow]);
await Container.get(ActiveWorkflowRunner).add(
workflowId,
shared.workflow.active ? 'update' : 'activate',
);
@@ -383,14 +384,14 @@ export class WorkflowsService {
nodes: workflowData.nodes,
connections: workflowData.connections,
active: false,
nodeTypes: NodeTypes(),
nodeTypes: Container.get(NodeTypes),
staticData: undefined,
settings: workflowData.settings,
});
const additionalData = await WorkflowExecuteAdditionalData.getBase(user.id);
const needsWebhook = await TestWebhooks.getInstance().needsWebhookData(
const needsWebhook = await Container.get(TestWebhooks).needsWebhookData(
workflowData,
workflow,
additionalData,
@@ -436,7 +437,7 @@ export class WorkflowsService {
}
static async delete(user: User, workflowId: string): Promise<WorkflowEntity | undefined> {
await ExternalHooks().run('workflow.delete', [workflowId]);
await Container.get(ExternalHooks).run('workflow.delete', [workflowId]);
const sharedWorkflow = await Db.collections.SharedWorkflow.findOne({
relations: ['workflow', 'role'],
@@ -454,13 +455,13 @@ export class WorkflowsService {
if (sharedWorkflow.workflow.active) {
// deactivate before deleting
await ActiveWorkflowRunner.getInstance().remove(workflowId);
await Container.get(ActiveWorkflowRunner).remove(workflowId);
}
await Db.collections.Workflow.delete(workflowId);
void InternalHooksManager.getInstance().onWorkflowDeleted(user, workflowId, false);
await ExternalHooks().run('workflow.afterDelete', [workflowId]);
void Container.get(InternalHooks).onWorkflowDeleted(user, workflowId, false);
await Container.get(ExternalHooks).run('workflow.afterDelete', [workflowId]);
return sharedWorkflow.workflow;
}