UNPKG

n8n

Version:

n8n Workflow Automation Tool

148 lines 6.46 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.N8NCheckpointStorage = void 0; const backend_common_1 = require("@n8n/backend-common"); const config_1 = require("@n8n/config"); const constants_1 = require("@n8n/constants"); 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"); const agent_checkpoint_repository_1 = require("../repositories/agent-checkpoint.repository"); let N8NCheckpointStorage = class N8NCheckpointStorage { constructor(instanceSettings, agentCheckpointRepository, logger, agentsConfig, moduleRegistry) { this.instanceSettings = instanceSettings; this.agentCheckpointRepository = agentCheckpointRepository; this.logger = logger; this.agentsConfig = agentsConfig; this.moduleRegistry = moduleRegistry; this.isStopping = false; this.isInitialized = false; this.logger = this.logger.scoped('agents'); this.isInitialized = this.moduleRegistry.isActive('agents'); } getStorage(agentId) { return { save: async (key, state) => await this.save(key, state, agentId), load: async (key) => await this.load(key), delete: async (key) => await this.delete(key), }; } init() { (0, node_assert_1.strict)(this.instanceSettings.instanceRole !== 'unset', 'Instance role is not set'); if (this.instanceSettings.isLeader) this.startPruning(); } async save(key, state, agentId = null) { const existing = await this.agentCheckpointRepository.findOneBy({ runId: key }); if (existing) { existing.state = JSON.stringify(state); existing.expired = false; await this.agentCheckpointRepository.save(existing); } else { const checkpoint = this.agentCheckpointRepository.create({ runId: key, agentId, state: JSON.stringify(state), expired: false, }); await this.agentCheckpointRepository.save(checkpoint); } } async load(key) { const checkpoint = await this.agentCheckpointRepository.findOneBy({ runId: key }); if (!checkpoint) return undefined; if (checkpoint.expired || checkpoint.state === null) { throw new n8n_workflow_1.UserError('This action has expired and cannot be resumed'); } return (0, n8n_workflow_1.jsonParse)(checkpoint.state); } async getStatus(key) { const checkpoint = await this.agentCheckpointRepository.findOneBy({ runId: key }); if (!checkpoint) return { status: 'not-found' }; if (checkpoint.expired || checkpoint.state === null) return { status: 'expired' }; return { status: 'active', checkpoint: (0, n8n_workflow_1.jsonParse)(checkpoint.state) }; } async delete(key) { await this.agentCheckpointRepository.update({ runId: key }, { expired: true, state: null }); } startPruning() { this.isStopping = false; this.scheduleNextPrune(0); } stopPruning() { clearTimeout(this.pruneTimeout); this.pruneTimeout = undefined; } shutdown() { this.isStopping = true; this.stopPruning(); } scheduleNextPrune(delayMs = constants_1.Time.hours.toMilliseconds) { if (this.isStopping || !this.isInitialized) return; this.pruneTimeout = setTimeout(async () => { await this.pruneStaleSuspensions(); }, delayMs); } async pruneStaleSuspensions() { const ttlMs = this.agentsConfig.checkpointTtlSeconds * constants_1.Time.seconds.toMilliseconds; const cutoffDate = new Date(Date.now() - ttlMs); try { const count = await this.agentCheckpointRepository.markExpired(cutoffDate); if (count > 0) { this.logger.info('Marked stale agent checkpoints as expired', { count }); } else { this.logger.debug('No stale agent checkpoints to expire'); } this.scheduleNextPrune(); } catch (error) { this.logger.warn('Failed to expire stale agent checkpoints', { error }); this.scheduleNextPrune(constants_1.Time.seconds.toMilliseconds * 30); } } }; exports.N8NCheckpointStorage = N8NCheckpointStorage; __decorate([ (0, decorators_1.OnLeaderTakeover)(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], N8NCheckpointStorage.prototype, "startPruning", null); __decorate([ (0, decorators_1.OnLeaderStepdown)(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], N8NCheckpointStorage.prototype, "stopPruning", null); __decorate([ (0, decorators_1.OnShutdown)(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], N8NCheckpointStorage.prototype, "shutdown", null); exports.N8NCheckpointStorage = N8NCheckpointStorage = __decorate([ (0, di_1.Service)(), __metadata("design:paramtypes", [n8n_core_1.InstanceSettings, agent_checkpoint_repository_1.AgentCheckpointRepository, backend_common_1.Logger, config_1.AgentsConfig, backend_common_1.ModuleRegistry]) ], N8NCheckpointStorage); //# sourceMappingURL=n8n-checkpoint-storage.js.map