UNPKG

redis-smq

Version:

A simple high-performance Redis message queue for Node.js.

141 lines 5.71 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DequeueMessage = void 0; const os = require("os"); const types_1 = require("../../../../types"); const redis_keys_1 = require("../../../common/redis-keys/redis-keys"); const redis_smq_common_1 = require("redis-smq-common"); const events_1 = require("../../../common/events/events"); const message_1 = require("../../message/message"); const queue_rate_limit_1 = require("../../queue-manager/queue-rate-limit"); const queue_1 = require("../../queue-manager/queue"); const redis_client_1 = require("../../../common/redis-client/redis-client"); const queue_not_found_error_1 = require("../../queue-manager/errors/queue-not-found.error"); const IPAddresses = (() => { var _a; const nets = os.networkInterfaces(); const addresses = []; for (const netInterface in nets) { const addr = (_a = nets[netInterface]) !== null && _a !== void 0 ? _a : []; for (const netAddr of addr) { if (netAddr.family === 'IPv4' && !netAddr.internal) { addresses.push(netAddr.address); } } } return addresses; })(); class DequeueMessage { constructor(messageHandler, redisClient) { this.queueRateLimit = null; this.queueType = null; this.messageHandler = messageHandler; this.redisClient = redisClient; this.queue = messageHandler.getQueue(); this.consumerId = messageHandler.getConsumerId(); this.redisKeys = redis_keys_1.redisKeys.getQueueConsumerKeys(this.queue, this.consumerId); this.ticker = new redis_smq_common_1.Ticker(() => this.dequeue()); } dequeueMessageWithPriority(cb) { this.redisClient.zpophgetrpush(this.redisKeys.keyQueuePendingPriorityMessageWeight, this.redisKeys.keyQueuePendingPriorityMessages, this.redisKeys.keyQueueProcessing, cb); } waitForMessage(cb) { this.redisClient.brpoplpush(this.redisKeys.keyQueuePending, this.redisKeys.keyQueueProcessing, 0, cb); } dequeueMessage(cb) { this.redisClient.rpoplpush(this.redisKeys.keyQueuePending, this.redisKeys.keyQueueProcessing, cb); } dequeue() { const cb = (err, reply) => { if (err) { this.ticker.abort(); this.messageHandler.handleError(err); } else if (typeof reply === 'string') { const message = message_1.Message.createFromMessage(reply); this.messageHandler.emit(events_1.events.MESSAGE_RECEIVED, message); } else { this.ticker.nextTick(); } }; const deq = () => { if (this.isPriorityQueuingEnabled()) this.dequeueMessageWithPriority(cb); else this.dequeueMessage(cb); }; if (this.isPriorityQueuingEnabled() || this.queueRateLimit) { if (this.queueRateLimit) { queue_rate_limit_1.QueueRateLimit.hasExceeded(this.redisClient, this.queue, this.queueRateLimit, (err, isExceeded) => { if (err) this.messageHandler.handleError(err); else if (isExceeded) this.ticker.nextTick(); else deq(); }); } else deq(); } else { this.waitForMessage(cb); } } isPriorityQueuingEnabled() { return this.queueType === types_1.EQueueType.PRIORITY_QUEUE; } run(cb) { redis_smq_common_1.async.waterfall([ (cb) => { const { keyQueues, keyQueueConsumers, keyConsumerQueues, keyQueueProcessing, keyProcessingQueues, keyQueueProcessingQueues, } = this.redisKeys; const consumerInfo = { ipAddress: IPAddresses, hostname: os.hostname(), pid: process.pid, createdAt: Date.now(), }; this.redisClient.runScript(redis_client_1.ELuaScriptName.INIT_CONSUMER_QUEUE, [ keyQueues, keyQueueConsumers, keyConsumerQueues, keyProcessingQueues, keyQueueProcessingQueues, ], [ this.consumerId, JSON.stringify(consumerInfo), JSON.stringify(this.queue), keyQueueProcessing, ], (err, reply) => { if (err) cb(err); else if (!reply) cb(new queue_not_found_error_1.QueueNotFoundError()); else cb(); }); }, (cb) => { queue_1.Queue.getSettings(this.messageHandler.getConfig(), this.redisClient, this.queue, (err, reply) => { var _a; if (err) cb(err); else if (!reply) cb(new redis_smq_common_1.errors.EmptyCallbackReplyError()); else { this.queueType = reply.type; this.queueRateLimit = (_a = reply.rateLimit) !== null && _a !== void 0 ? _a : null; cb(); } }); }, ], cb); } quit(cb) { this.ticker.once(events_1.events.DOWN, cb); this.ticker.quit(); } } exports.DequeueMessage = DequeueMessage; //# sourceMappingURL=dequeue-message.js.map