UNPKG

peanar

Version:

A job queue for Node.js based on RabbitMQ

113 lines (112 loc) 3.85 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const debug_1 = __importDefault(require("debug")); const debug = (0, debug_1.default)('peanar:broker'); const ts_amqp_1 = require("ts-amqp"); const ChannelPool_1 = __importDefault(require("ts-amqp/dist/classes/ChannelPool")); const exceptions_1 = require("./exceptions"); /** * Peanar's broker adapter */ class PeanarBroker { config; conn; _connectPromise; pool; constructor(config) { this.config = config; } _connect = async () => { debug('_connect()'); const conn = (this.conn = new ts_amqp_1.Connection(this.config.connection)); this.pool = new ChannelPool_1.default(conn, this.config.poolSize, this.config.prefetch); await conn.start(); await this.pool.open(); conn.once('close', (err) => { this._connectPromise = undefined; if (err && err.reply_code >= 400) { this.connect(); } }); }; /** * Initializes adapter connection and channel */ connect = async () => { if (this._connectPromise) return this._connectPromise; return (this._connectPromise = this._connect()); }; async shutdown() { debug('shutdown()'); if (this.pool) { await this.pool.close(); this.pool = undefined; debug('pool closed.'); } if (this.conn) { this.conn.off('close', this.connect); await this.conn.close(); this.conn = undefined; debug('connection closed.'); } } async queues(queues) { await this.connect(); if (!this.pool) throw new exceptions_1.PeanarAdapterError('Not connected!'); return await Promise.all(this.pool.mapOver(queues, async (ch, queue) => { return ch.declareQueue(queue); })); } async exchanges(exchanges) { await this.connect(); if (!this.pool) throw new exceptions_1.PeanarAdapterError('Not connected!'); return await Promise.all(this.pool.mapOver(exchanges, async (ch, exchange) => { return ch.declareExchange(exchange); })); } async bindings(bindings) { await this.connect(); if (!this.pool) throw new exceptions_1.PeanarAdapterError('Not connected!'); return await Promise.all(this.pool.mapOver(bindings, async (ch, binding) => { return ch.bindQueue(binding); })); } consume(queue) { if (!this.pool) throw new exceptions_1.PeanarAdapterError('Not connected!'); return this.pool.acquireAndRun(ch => ch.basicConsume(queue)); } consumeOver(queues) { if (!this.pool) throw new exceptions_1.PeanarAdapterError('Not connected!'); return this.pool.mapOver(queues, async (ch, queue) => { return { queue, consumer: await ch.basicConsume(queue) }; }); } async publish(message) { await this.connect(); if (!this.pool) throw new exceptions_1.PeanarAdapterError('Not connected!'); const { channel, release } = await this.pool.acquire(); debug(`publish to channel ${channel.channelNumber}`); if (channel.basicPublishJson(message.exchange || '', message.routing_key, message.properties, message.body, message.mandatory, message.immediate)) { release(); return true; } else { channel.once('drain', release); return false; } } } exports.default = PeanarBroker;