onirii
Version:
Universal queue SDK
310 lines (309 loc) • 12.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AmqpChannelService = void 0;
const tslib_1 = require("tslib");
const log_factory_1 = require("../../factory/log-factory");
const amqp_original_consumer_wrapper_1 = require("../../wrapper/amqp-original-consumer-wrapper");
/**
* Channel Service
*
* @since 1.0.0
* @date 2021-06-02
* @author Luminous(BGLuminous)
*/
class AmqpChannelService {
/**
* Constructor this need inject current amqp channel instance to create
*
* @param {string} name identify name
* @param {amqp.Channel | amqp.ConfirmChannel} channel current amqp channel
*/
constructor(name, channel) {
// original consume pool
this.originalConsumerPool = [];
// consumer position
this.consumerPosition = -1;
this.instanceName = name;
// init logger
this.logger = log_factory_1.LogFactory.create(name.substr(0, this.instanceName.lastIndexOf('-')));
this.logger.info(`Creating Channel Service ${this.instanceName}`);
// inject amqp channel/confirmChannel instance
if (!channel) {
throw new Error('Channel Service Inject Error, Current Amqp Channel Undefined');
}
this.currentChannelInstance = channel;
this.addDefaultListener();
}
/**
* Add default listener for each connect service instance
*
* @private
*/
addDefaultListener() {
this.addErrorListener((err) => {
this.logger.error(`Amqp Channel(${this.instanceName}) Got Error: ${err} ${JSON.stringify(err)}`);
});
this.addCloseListener(() => {
this.logger.error(`Amqp Channel(${this.instanceName}) Closed`);
});
}
/**
* add close event listener
*
* @param process event emit callback
*/
addCloseListener(process) {
var _a;
(_a = this.currentChannelInstance) === null || _a === void 0 ? void 0 : _a.on('close', () => {
process();
});
}
/**
* add error event listener
*
* @param process event emit callback
*/
addErrorListener(process) {
var _a;
(_a = this.currentChannelInstance) === null || _a === void 0 ? void 0 : _a.on('error', err => process(err));
}
/**
* add return event listener
*
* @param process event emit callback
*/
addReturnListener(process) {
var _a;
(_a = this.currentChannelInstance) === null || _a === void 0 ? void 0 : _a.on('return', err => process(err));
}
/**
* add drain event listener
*
* @param process event emit callback
*/
addDrainListener(process) {
var _a;
(_a = this.currentChannelInstance) === null || _a === void 0 ? void 0 : _a.on('drain', () => process());
}
/**
* initialize mq exchange/queue/bind
*
* @param config exchange/queue/bind config
*/
initMetaConfigure(config) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
if (config.queueList && config.queueList.length !== 0) {
yield this.initQueueConfigure(config.queueList);
}
if (config.exchangeList && config.exchangeList.length !== 0) {
yield this.initExchangeConfigure(config.exchangeList);
}
if (config.bindList && config.bindList.length !== 0) {
yield this.initBindConfigure(config.bindList);
}
});
}
/**
* initialize mq queue
*
* @param config queue config data
* @param cleanMode delete then create
*/
initQueueConfigure(config, cleanMode = false) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
try {
for (let amqpQueue of config) {
if (cleanMode) {
yield this.currentChannelInstance.deleteQueue(amqpQueue.name, amqpQueue.cleanOption);
}
yield this.currentChannelInstance.assertQueue(amqpQueue.name, amqpQueue.options);
}
}
catch (err) {
this.logger.error(`${this.instanceName} initQueueConfigure() Got Error: ${JSON.stringify(err)}`);
throw err;
}
});
}
/**
* initialize mq exchange
*
* @param config exchange config data
* @param cleanMode delete then create
*/
initExchangeConfigure(config, cleanMode = false) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
try {
for (let amqpExchange of config) {
if (cleanMode) {
yield this.currentChannelInstance.deleteExchange(amqpExchange.name, amqpExchange.cleanOption);
}
yield this.currentChannelInstance.assertExchange(amqpExchange.name, amqpExchange.type, amqpExchange.options);
}
}
catch (err) {
this.logger.error(`${this.instanceName} initExchangeConfigure() Got Error: ${JSON.stringify(err)}`);
throw err;
}
});
}
/**
* initialize mq bind
*
* @param config bind config data
*/
initBindConfigure(config) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
try {
for (let amqpBind of config) {
if (amqpBind.type === 'qte') {
yield this.bindQueueToExchange(amqpBind.fromSourceName, amqpBind.targetSourceName, amqpBind.key, amqpBind.options);
}
else if (amqpBind.type === 'ete') {
yield this.bindExchangeToExchange(amqpBind.fromSourceName, amqpBind.targetSourceName, amqpBind.key, amqpBind.options);
}
}
}
catch (err) {
this.logger.error(`${this.instanceName} initBindConfigure() Got Error: ${JSON.stringify(err)}`);
throw err;
}
});
}
ackAllMessage() {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
yield this.currentChannelInstance.ackAll();
});
}
ackMessage(message, allUp) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
yield this.currentChannelInstance.ack(message, allUp);
});
}
consume(queue, processor, options) {
const consumerName = (options === null || options === void 0 ? void 0 : options.consumerTag) || this.getNextConsumerName();
const originalConsumer = new amqp_original_consumer_wrapper_1.AmqpOriginalConsumerWrapper(consumerName, this, queue, processor, options);
this.originalConsumerPool.push(originalConsumer);
return originalConsumer;
}
getCurrentMessage(queueName, options) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.currentChannelInstance.get(queueName, options);
});
}
killConsume(consumerName) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
const targetConsumer = this.originalConsumerPool.find(element => element.consumerName === consumerName);
if (targetConsumer) {
yield targetConsumer.kill();
this.originalConsumerPool = this.originalConsumerPool.filter(element => element.consumerName !== consumerName);
return true;
}
this.logger.error(`Can't Kill Unknown Consumer ${consumerName}`);
return false;
});
}
nackAllMessage(reQueue) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
this.currentChannelInstance.nackAll(reQueue);
});
}
recover() {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.currentChannelInstance.recover();
});
}
rejectMessage(message, allUp, reQueue) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
try {
this.currentChannelInstance.reject(message, reQueue);
}
catch (err) {
this.currentChannelInstance.nack(message, allUp, reQueue);
}
});
}
sendMessageToExchange(exchangeName, key, content, options) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.currentChannelInstance.publish(exchangeName, key, content, options);
});
}
sendMessageToQueue(queueName, content, options) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.currentChannelInstance.sendToQueue(queueName, content, options);
});
}
setPrefetchCount(count, global) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.currentChannelInstance.prefetch(count, global);
});
}
bindExchangeToExchange(target, from, key, args) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.currentChannelInstance.bindExchange(target, from, key, args);
});
}
createExchangeIfNotExist(name, type, options) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.currentChannelInstance.assertExchange(name, type, options);
});
}
deleteExchange(name, options) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.currentChannelInstance.deleteExchange(name, options);
});
}
getExchangeStatus(name) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.currentChannelInstance.checkExchange(name);
});
}
unbindExchangeToExchange(target, from, key, args) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.currentChannelInstance.unbindExchange(target, from, key, args);
});
}
bindQueueToExchange(name, exchange, bindKey, args) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.currentChannelInstance.bindQueue(name, exchange, bindKey, args);
});
}
createQueueIfNotExist(name, options) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.currentChannelInstance.assertQueue(name, options);
});
}
deleteQueue(name, options) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.currentChannelInstance.deleteQueue(name, options);
});
}
getQueueStatus(name) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.currentChannelInstance.checkQueue(name);
});
}
purgeQueue(name) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
this.logger.warn(`Purging Queue ${name}`);
return this.currentChannelInstance.purgeQueue(name);
});
}
unbindQueueToExchange(name, exchange, bindKey, args) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.currentChannelInstance.unbindQueue(name, exchange, bindKey, args);
});
}
close() {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
yield Promise.all(this.originalConsumerPool.map(element => element.kill()));
yield this.currentChannelInstance.close();
this.logger.warn(`Killed Channel ${this.instanceName}`);
});
}
getNextConsumerName() {
this.consumerPosition++;
return `${this.instanceName}-consumer-${this.consumerPosition}`;
}
}
exports.AmqpChannelService = AmqpChannelService;