UNPKG

@n8n-plus/n8n-plus

Version:

n8n Workflow Automation Tool (plus edition)

144 lines 7.29 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.WorkflowHistoryCompactionService = void 0; const backend_common_1 = require("@n8n/backend-common"); const config_1 = require("@n8n/config"); const constants_1 = require("@n8n/constants"); const db_1 = require("@n8n/db"); const decorators_1 = require("@n8n/decorators"); const di_1 = require("@n8n/di"); const n8n_core_1 = require("n8n-core"); const n8n_workflow_1 = require("n8n-workflow"); const node_assert_1 = require("node:assert"); let WorkflowHistoryCompactionService = class WorkflowHistoryCompactionService { constructor(config, logger, instanceSettings, dbConnection, workflowHistoryRepository) { this.config = config; this.logger = logger; this.instanceSettings = instanceSettings; this.dbConnection = dbConnection; this.workflowHistoryRepository = workflowHistoryRepository; this.isShuttingDown = false; this.logger = this.logger.scoped('workflow-history-compaction'); } init() { (0, node_assert_1.strict)(this.instanceSettings.instanceRole !== 'unset', 'Instance role is not set'); if (this.instanceSettings.isLeader) this.startCompacting(); } get isEnabled() { return this.instanceSettings.instanceType === 'main' && this.instanceSettings.isLeader; } startCompacting() { const { connectionState } = this.dbConnection; if (!this.isEnabled || !connectionState.migrated || this.isShuttingDown) return; this.logger.debug('Started workflow histories compaction', { ...this.config }); this.scheduleRollingCompacting(); if (this.config.compactOnStartUp) { this.logger.debug('Compacting on start up'); void this.compactHistories(); } } stopCompacting() { if (!this.compactingInterval) return; clearInterval(this.compactingInterval); this.logger.debug('Stopped workflow histories compaction'); } scheduleRollingCompacting() { const rateMs = (this.config.compactingTimeWindowHours / 2) * constants_1.Time.hours.toMilliseconds; this.compactingInterval = setInterval(async () => await this.compactHistories(), rateMs); this.logger.debug(`Compacting histories every ${this.config.compactingTimeWindowHours / 2.0} hour(s)`); } shutdown() { this.isShuttingDown = true; this.stopCompacting(); } async compactHistories() { const compactionStartTime = Date.now(); const startDate = new Date(compactionStartTime - (this.config.compactingMinimumAgeHours + this.config.compactingTimeWindowHours) * constants_1.Time.hours.toMilliseconds); const endDate = new Date(compactionStartTime - this.config.compactingMinimumAgeHours * constants_1.Time.hours.toMilliseconds); const startIso = startDate.toISOString(); const endIso = endDate.toISOString(); this.logger.info('Starting workflow history compaction', { dateRange: { start: startIso, end: endIso }, config: this.config, }); const workflowIds = await this.workflowHistoryRepository.getWorkflowIdsInRange(startDate, endDate); this.logger.debug(`Found ${workflowIds.length} workflows with versions between ${startIso} and ${endIso}`); let batchSum = 0; let totalVersionsSeen = 0; let totalVersionsDeleted = 0; let errorCount = 0; for (const [index, workflowId] of workflowIds.entries()) { try { const { seen, deleted } = await this.workflowHistoryRepository.pruneHistory(workflowId, startDate, endDate, this.config.minimumTimeBetweenSessionsMs); batchSum += seen; totalVersionsSeen += seen; totalVersionsDeleted += deleted; this.logger.debug(`Deleted ${deleted} of ${seen} versions of workflow ${workflowId} between ${startIso} and ${endIso}`); } catch (error) { errorCount += 1; this.logger.error(`Failed to prune version history of workflow ${workflowId}`, { error: (0, n8n_workflow_1.ensureError)(error), }); await (0, n8n_workflow_1.sleep)(this.config.batchDelayMs); } if (batchSum > this.config.batchSize) { this.logger.warn(`Encountered more than ${this.config.batchSize} workflow versions, waiting ${this.config.batchDelayMs * constants_1.Time.milliseconds.toSeconds} second(s) before continuing.`); this.logger.warn(`Compacted ${index} of ${workflowIds.length} workflows with versions between ${startIso} and ${endIso}`); await (0, n8n_workflow_1.sleep)(this.config.batchDelayMs); batchSum = 0; } } const durationMs = Date.now() - compactionStartTime; this.logger.info('Workflow history compaction complete', { workflowsProcessed: workflowIds.length, totalVersionsSeen, totalVersionsDeleted, errorCount, durationMs, dateRange: { start: startIso, end: endIso }, }); } }; exports.WorkflowHistoryCompactionService = WorkflowHistoryCompactionService; __decorate([ (0, decorators_1.OnLeaderTakeover)(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], WorkflowHistoryCompactionService.prototype, "startCompacting", null); __decorate([ (0, decorators_1.OnLeaderStepdown)(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], WorkflowHistoryCompactionService.prototype, "stopCompacting", null); __decorate([ (0, decorators_1.OnShutdown)(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], WorkflowHistoryCompactionService.prototype, "shutdown", null); exports.WorkflowHistoryCompactionService = WorkflowHistoryCompactionService = __decorate([ (0, di_1.Service)(), __metadata("design:paramtypes", [config_1.WorkflowHistoryCompactionConfig, backend_common_1.Logger, n8n_core_1.InstanceSettings, db_1.DbConnection, db_1.WorkflowHistoryRepository]) ], WorkflowHistoryCompactionService); //# sourceMappingURL=workflow-history-compaction.service.js.map