UNPKG

n8n

Version:

n8n Workflow Automation Tool

143 lines 5.56 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MultiMainSetupV2 = void 0; const node_assert_1 = __importDefault(require("node:assert")); class MultiMainSetupV2 { get hostId() { return this.instanceSettings.hostId; } constructor(logger, instanceSettings, errorReporter, client, emit) { this.logger = logger; this.instanceSettings = instanceSettings; this.errorReporter = errorReporter; this.client = client; this.emit = emit; this.leaderCheckInProgress = false; } async init() { const result = await this.client.setLeaderIfNotExists(); if (!result.ok) { this.logRedisCommandFailure('Failed to set leader key in Redis during init', result.error); this.instanceSettings.markAsFollower(); } else if (result.result) { this.takeOverAsLeader(); } else { this.instanceSettings.markAsFollower(); } } async shutdown() { const { isLeader } = this.instanceSettings; if (isLeader) { const result = await this.client.clearLeader(); if (!result.ok) { this.logger.warn('Failed to clear leader key from Redis', { error: result.error }); } } this.client.destroy(); } async checkLeader() { if (this.leaderCheckInProgress) { this.logger.warn('Previous leader check is still in progress, skipping this check'); return; } this.leaderCheckInProgress = true; try { if (this.instanceSettings.isLeader) { await this.checkAreWeStillLeader(); } else { await this.checkCanBecomeLeader(); } } finally { this.leaderCheckInProgress = false; } } async checkAreWeStillLeader() { (0, node_assert_1.default)(this.instanceSettings.isLeader); const renewTtlResult = await this.client.tryRenewLeaderTtl(); if (!renewTtlResult.ok) { this.logRedisCommandFailure('Failed to renew leader TTL', renewTtlResult.error); return; } const renewalResult = renewTtlResult.result; if (renewalResult.id === 'success') { this.logger.debug(`[Instance ID ${this.hostId}] Leader is this instance`); return; } this.logger.warn('[Multi-main setup] Leader failed to renew leader key'); if (renewalResult.id === 'other-host-is-leader') { this.logger.debug(`[Instance ID ${this.hostId}] Leader is other instance "${renewalResult.currentLeaderId}"`); this.stepDownToFollower(); return; } (0, node_assert_1.default)(renewalResult.id === 'key-missing'); const result = await this.client.setLeaderIfNotExists(); if (!result.ok) { this.logRedisCommandFailure('Failed to set leader key in Redis', result.error); this.stepDownToFollower(); return; } const wasSet = result.result; if (!wasSet) { this.stepDownToFollower(); } } async checkCanBecomeLeader() { (0, node_assert_1.default)(!this.instanceSettings.isLeader); const getResult = await this.client.getLeader(); if (!getResult.ok) { this.logRedisCommandFailure('Failed to get leader key from Redis', getResult.error); return; } const leaderId = getResult.result; if (leaderId && leaderId === this.hostId) { this.errorReporter.info(`[Instance ID ${this.hostId}] Remote/Local leadership mismatch, marking self as leader`, { shouldBeLogged: true, shouldReport: true, }); this.takeOverAsLeader(); return; } if (leaderId) { this.logger.debug(`[Instance ID ${this.hostId}] Leader is other instance "${leaderId}"`); return; } this.logger.debug(`[Instance ID ${this.hostId}] Leadership vacant, attempting to become leader...`); const result = await this.client.setLeaderIfNotExists(); if (!result.ok) { this.logger.warn('Failed to try leader key set in Redis', { error: result.error }); return; } const wasSet = result.result; if (wasSet) { this.takeOverAsLeader(); } } takeOverAsLeader() { (0, node_assert_1.default)(!this.instanceSettings.isLeader); this.logger.info(`[Instance ID ${this.hostId}] Leader is now this instance`); this.instanceSettings.markAsLeader(); this.emit('leader-takeover'); } stepDownToFollower() { (0, node_assert_1.default)(this.instanceSettings.isLeader); this.logger.info(`[Instance ID ${this.hostId}] This is now a follower instance`); this.instanceSettings.markAsFollower(); this.emit('leader-stepdown'); } async fetchLeaderKey() { const result = await this.client.getLeader(); return result.ok ? result.result : null; } logRedisCommandFailure(message, error) { this.logger.warn(`${message}: ${error.message}`, { error }); } } exports.MultiMainSetupV2 = MultiMainSetupV2; //# sourceMappingURL=multi-main-setup-v2.js.map