dl
Version:
DreamLab Libs
132 lines (104 loc) • 4.71 kB
JavaScript
var core = require('core');
var RbmqIncomingMessage = core.client.rabbitmq.RbmqIncomingMessage;
var QueueIncomingMessage = function (rbmqIncomingMessage, logger, messageProcessor) {
if (!(rbmqIncomingMessage instanceof RbmqIncomingMessage)) {
throw new Error('QueueIncomingMessage can be instantied only from RbmqIncomingMessage');
}
this._logger = logger;
this._messageProcessor = messageProcessor;
for (var key in rbmqIncomingMessage) {
if (rbmqIncomingMessage.hasOwnProperty(key)) {
this[key] = rbmqIncomingMessage[key];
}
}
this._xMsgCreated = parseInt(this.getHeader('x-msg-created', Date.now()));
this._xMsgModified = parseInt(this.getHeader('x-msg-modified', Date.now()));
this._xMsgReceived = Date.now();
// override routing key from _postpone_queue-name_ to actual routing key before postpone
if (this.hasHeader('x-postpone-routing-key')) {
this._data['routingKey'] = this.getHeader('x-postpone-routing-key');
}
this._postponeCount = 0;
if (this.hasHeader('x-postpone-count')) {
this._postponeCount = parseInt(this.getHeader('x-postpone-count', 0));
} else if (this.hasHeader('x-death')) {
this._parseDLEPostponeHeaders(this.getHeader('x-death', []));
}
this.removeHeader('x-postpone-count');
this.removeHeader('x-postpone-routing-key');
this.removeHeader('x-death');
this.removeHeader('x-msg-created');
this.removeHeader('x-msg-modified');
this._logger.log('subscribe', 'delay', this.getDelay(), this.getMessageId());
};
QueueIncomingMessage.prototype = Object.create(RbmqIncomingMessage.prototype);
QueueIncomingMessage.prototype._parseDLEPostponeHeaders = function (deathHeader) {
var rejectAction;
var postponeAction;
// in death header should be at least two items - one for reject from original queue
// and second from expiration from postpone queue
for (var i = 0, l = deathHeader.length; i < l; i++) {
var el = deathHeader[i];
var rKeys = el['routing-keys'];
if (el.reason === 'expired' && rKeys.length === 1 && rKeys[0].indexOf('_postpone_') === 0) {
postponeAction = el;
}
if (el.reason === 'rejected') {
rejectAction = el;
}
}
// when both actions occured the message has been postponed - set postpone count and original routing key
if (postponeAction && rejectAction) {
this._postponeCount = rejectAction.count;
this._data['routingKey'] = rejectAction['routing-keys'][0];
this._xMsgModified = rejectAction.time;
}
};
QueueIncomingMessage.prototype.getBody = function() {
var body = RbmqIncomingMessage.prototype.getBody.call(this);
// if postponer is enabled we must keep message body untouched in case of future postpone
// this is not enabled when postpone is not enabled - and it should not be for large messages
if (this._messageProcessor.isPostponerEnabled()) {
if (body instanceof Buffer) {
var buf = new Buffer(body.length);
body.copy(buf);
return body;
} else {
return JSON.parse(JSON.stringify(body));
}
}
return body;
};
QueueIncomingMessage.prototype.getHeaders = function() {
var headers = RbmqIncomingMessage.prototype.getHeaders.call(this);
return JSON.parse(JSON.stringify(headers));
};
QueueIncomingMessage.prototype.getDelay = function() {
return Date.now() - this._xMsgCreated;
};
QueueIncomingMessage.prototype.getClientDelay = function() {
return Date.now() - this._xMsgReceived;
};
QueueIncomingMessage.prototype.getCreateTimestamp = function() {
return this._xMsgCreated;
};
QueueIncomingMessage.prototype.getModifiedTimestamp = function() {
return this._xMsgModified;
};
QueueIncomingMessage.prototype.getPostponeCount = function() {
return this._postponeCount;
};
QueueIncomingMessage.prototype.acknowledge = function() {
this._logger.log('subscribe', 'ack.delay', this.getClientDelay(), this.getMessageId());
this._messageProcessor.acknowledge(this);
};
QueueIncomingMessage.prototype.reject = function(requeue) {
this._logger.log('subscribe', 'reject.delay', this.getClientDelay(), this.getMessageId());
this._messageProcessor.reject(this, requeue);
};
QueueIncomingMessage.prototype.postpone = function(delay) {
this._logger.log('subscribe', 'postpone.delay', this.getClientDelay(), this.getMessageId());
this._logger.log('subscribe', 'postpone.rounds', this.getPostponeCount() + 1, this.getMessageId());
this._messageProcessor.postpone(this, delay);
};
exports.QueueIncomingMessage = QueueIncomingMessage;