UNPKG

rabbitmq-enterprise-toolkit

Version:

🚀 Enterprise-grade RabbitMQ wrapper for Node.js & TypeScript - High-throughput messaging with automatic retry, DLQ, batch processing & graceful shutdown. Production-ready AMQP client with zero message loss guarantee.

131 lines • 4.41 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConnectionManager = void 0; const amqplib_1 = require("amqplib"); const errors_1 = require("../utils/errors"); const helpers_1 = require("../utils/helpers"); class ConnectionManager { constructor(config) { this.config = config; this.connection = null; this.channel = null; this.isReconnecting = false; } async connect() { if (this.isConnected()) { return; } try { const url = this.buildConnectionUrl(); // Cast to our extended interface for proper typing this.connection = (await (0, amqplib_1.connect)(url, { heartbeat: this.config.heartbeat || 60 })); this.channel = await this.connection.createChannel(); this.setupConnectionHandlers(); console.log('RabbitMQ connection established'); } catch (error) { throw new errors_1.ConnectionError('Failed to connect to RabbitMQ', { error: (0, helpers_1.formatError)(error) }); } } async reconnect(onReconnected) { if (this.isReconnecting) { return; } this.onReconnectedCallback = onReconnected; this.isReconnecting = true; const delay = this.config.reconnectDelay || 5000; try { console.log(`Reconnecting to RabbitMQ in ${delay}ms...`); await this.sleep(delay); // Reset connection before reconnecting this.connection = null; this.channel = null; await this.connect(); if (this.onReconnectedCallback) { await this.onReconnectedCallback(); } console.log('RabbitMQ reconnection successful'); } catch (error) { console.error('Reconnection failed:', (0, helpers_1.formatError)(error)); // Retry reconnection setTimeout(() => { this.isReconnecting = false; this.reconnect(this.onReconnectedCallback); }, delay); } finally { this.isReconnecting = false; } } getChannel() { if (!this.channel) { throw new errors_1.ConnectionError('Channel not available'); } return this.channel; } isConnected() { try { return !!(this.connection && this.channel && // Check if connection is not destroyed !this.connection.connection?.destroyed); } catch (error) { return false; } } async close() { try { if (this.channel) { await this.channel.close(); this.channel = null; } if (this.connection) { await this.connection.close(); this.connection = null; } console.log('RabbitMQ connection closed'); } catch (error) { console.error('Error closing connection:', (0, helpers_1.formatError)(error)); // Force reset even if close fails this.connection = null; this.channel = null; } } buildConnectionUrl() { const { host, port, username, password, vhost = '/', ssl = false } = this.config; return `amqp${ssl ? 's' : ''}://${username}:${password}@${host}:${port}${vhost}`; } setupConnectionHandlers() { if (!this.connection) return; this.connection.on('error', (error) => { console.error('RabbitMQ connection error:', error); this.handleConnectionError(); }); this.connection.on('close', () => { console.warn('RabbitMQ connection closed'); this.handleConnectionError(); }); } handleConnectionError() { // Reset connection state this.connection = null; this.channel = null; // Attempt reconnection if not already reconnecting if (!this.isReconnecting) { this.reconnect(this.onReconnectedCallback); } } sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } } exports.ConnectionManager = ConnectionManager; //# sourceMappingURL=connection.js.map