UNPKG

n8n

Version:

n8n Workflow Automation Tool

132 lines 6.26 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.WaitTracker = void 0; const di_1 = require("@n8n/di"); const n8n_core_1 = require("n8n-core"); const n8n_workflow_1 = require("n8n-workflow"); const active_executions_1 = require("./active-executions"); const execution_repository_1 = require("./databases/repositories/execution.repository"); const orchestration_service_1 = require("./services/orchestration.service"); const ownership_service_1 = require("./services/ownership.service"); const workflow_runner_1 = require("./workflow-runner"); let WaitTracker = class WaitTracker { constructor(logger, executionRepository, ownershipService, activeExecutions, workflowRunner, orchestrationService, instanceSettings) { this.logger = logger; this.executionRepository = executionRepository; this.ownershipService = ownershipService; this.activeExecutions = activeExecutions; this.workflowRunner = workflowRunner; this.orchestrationService = orchestrationService; this.instanceSettings = instanceSettings; this.waitingExecutions = {}; this.logger = this.logger.scoped('waiting-executions'); } has(executionId) { return this.waitingExecutions[executionId] !== undefined; } init() { const { isLeader, isMultiMain } = this.instanceSettings; if (isLeader) this.startTracking(); if (isMultiMain) { this.orchestrationService.multiMainSetup .on('leader-takeover', () => this.startTracking()) .on('leader-stepdown', () => this.stopTracking()); } } startTracking() { this.logger.debug('Started tracking waiting executions'); this.mainTimer = setInterval(() => { void this.getWaitingExecutions(); }, 60000); void this.getWaitingExecutions(); } async getWaitingExecutions() { this.logger.debug('Querying database for waiting executions'); const executions = await this.executionRepository.getWaitingExecutions(); if (executions.length === 0) { return; } const executionIds = executions.map((execution) => execution.id).join(', '); this.logger.debug(`Found ${executions.length} executions. Setting timer for IDs: ${executionIds}`); for (const execution of executions) { const executionId = execution.id; if (this.waitingExecutions[executionId] === undefined) { const triggerTime = execution.waitTill.getTime() - new Date().getTime(); this.waitingExecutions[executionId] = { executionId, timer: setTimeout(() => { void this.startExecution(executionId); }, triggerTime), }; } } } stopExecution(executionId) { if (!this.waitingExecutions[executionId]) return; clearTimeout(this.waitingExecutions[executionId].timer); delete this.waitingExecutions[executionId]; } async startExecution(executionId) { this.logger.debug(`Resuming execution ${executionId}`, { executionId }); delete this.waitingExecutions[executionId]; const fullExecutionData = await this.executionRepository.findSingleExecution(executionId, { includeData: true, unflattenData: true, }); if (!fullExecutionData) { throw new n8n_workflow_1.UnexpectedError('Execution does not exist.', { extra: { executionId } }); } if (fullExecutionData.finished) { throw new n8n_workflow_1.UnexpectedError('The execution did succeed and can so not be started again.'); } if (!fullExecutionData.workflowData.id) { throw new n8n_workflow_1.UnexpectedError('Only saved workflows can be resumed.'); } const workflowId = fullExecutionData.workflowData.id; const project = await this.ownershipService.getWorkflowProjectCached(workflowId); const data = { executionMode: fullExecutionData.mode, executionData: fullExecutionData.data, workflowData: fullExecutionData.workflowData, projectId: project.id, pushRef: fullExecutionData.data.pushRef, }; await this.workflowRunner.run(data, false, false, executionId); const { parentExecution } = fullExecutionData.data; if (parentExecution) { void this.activeExecutions.getPostExecutePromise(executionId).then(() => { void this.startExecution(parentExecution.executionId); }); } } stopTracking() { this.logger.debug('Shutting down wait tracking'); clearInterval(this.mainTimer); Object.keys(this.waitingExecutions).forEach((executionId) => { clearTimeout(this.waitingExecutions[executionId].timer); }); } }; exports.WaitTracker = WaitTracker; exports.WaitTracker = WaitTracker = __decorate([ (0, di_1.Service)(), __metadata("design:paramtypes", [n8n_core_1.Logger, execution_repository_1.ExecutionRepository, ownership_service_1.OwnershipService, active_executions_1.ActiveExecutions, workflow_runner_1.WorkflowRunner, orchestration_service_1.OrchestrationService, n8n_core_1.InstanceSettings]) ], WaitTracker); //# sourceMappingURL=wait-tracker.js.map