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
JavaScript
"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