@tsjing/nsqjs
Version:
NodeJS client for NSQ
209 lines (180 loc) • 6.67 kB
JavaScript
// Generated by CoffeeScript 1.10.0
var Debug, EventEmitter, NSQDConnection, Reader, ReaderConfig, ReaderRdy, RoundRobinList, _, lookup, request,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
_ = require('underscore');
Debug = require('debug');
request = require('request');
EventEmitter = require('events').EventEmitter;
ReaderConfig = require('./config').ReaderConfig;
NSQDConnection = require('./nsqdconnection').NSQDConnection;
ReaderRdy = require('./readerrdy').ReaderRdy;
RoundRobinList = require('./roundrobinlist');
lookup = require('./lookupd');
Reader = (function(superClass) {
extend(Reader, superClass);
Reader.ERROR = 'error';
Reader.MESSAGE = 'message';
Reader.DISCARD = 'discard';
Reader.NSQD_CONNECTED = 'nsqd_connected';
Reader.NSQD_CLOSED = 'nsqd_closed';
function Reader(topic, channel, options) {
this.topic = topic;
this.channel = channel;
this.debug = Debug("nsqjs:reader:" + this.topic + "/" + this.channel);
this.config = new ReaderConfig(options);
this.config.validate();
this.debug('Configuration');
this.debug(this.config);
this.roundrobinLookupd = new RoundRobinList(this.config.lookupdHTTPAddresses);
this.readerRdy = new ReaderRdy(this.config.maxInFlight, this.config.maxBackoffDuration, this.topic + "/" + this.channel);
this.connectIntervalId = null;
this.connectionIds = [];
}
Reader.prototype.connect = function() {
var delay, delayedStart, directConnect, interval;
interval = this.config.lookupdPollInterval * 1000;
delay = Math.random() * this.config.lookupdPollJitter * interval;
if (this.config.nsqdTCPAddresses.length) {
directConnect = (function(_this) {
return function() {
var addr, address, i, len, port, ref, ref1, results;
if (_this.isPaused()) {
return;
}
if (_this.connectionIds.length < _this.config.nsqdTCPAddresses.length) {
ref = _this.config.nsqdTCPAddresses;
results = [];
for (i = 0, len = ref.length; i < len; i++) {
addr = ref[i];
ref1 = addr.split(':'), address = ref1[0], port = ref1[1];
results.push(_this.connectToNSQD(address, Number(port)));
}
return results;
}
};
})(this);
delayedStart = (function(_this) {
return function() {
return _this.connectIntervalId = setInterval(directConnect.bind(_this), interval);
};
})(this);
directConnect();
return setTimeout(delayedStart, delay);
} else {
delayedStart = (function(_this) {
return function() {
return _this.connectIntervalId = setInterval(_this.queryLookupd.bind(_this), interval);
};
})(this);
this.queryLookupd();
return setTimeout(delayedStart, delay);
}
};
Reader.prototype.close = function() {
clearInterval(this.connectIntervalId);
return this.readerRdy.close();
};
Reader.prototype.pause = function() {
this.debug('pause');
return this.readerRdy.pause();
};
Reader.prototype.unpause = function() {
this.debug('unpause');
return this.readerRdy.unpause();
};
Reader.prototype.isPaused = function() {
return this.readerRdy.isPaused();
};
Reader.prototype.queryLookupd = function() {
var endpoint;
if (this.isPaused()) {
return;
}
endpoint = this.roundrobinLookupd.next();
return lookup(endpoint, this.topic, (function(_this) {
return function(err, nodes) {
var i, len, n, results;
if (!err) {
results = [];
for (i = 0, len = nodes.length; i < len; i++) {
n = nodes[i];
results.push(_this.connectToNSQD(n.broadcast_address, n.tcp_port));
}
return results;
}
};
})(this));
};
Reader.prototype.connectToNSQD = function(host, port) {
var conn;
this.debug("discovered " + host + ":" + port + " for " + this.topic + " topic");
conn = new NSQDConnection(host, port, this.topic, this.channel, this.config);
if (this.connectionIds.indexOf(conn.id()) !== -1) {
return;
}
this.debug("connecting to " + host + ":" + port);
this.connectionIds.push(conn.id());
this.registerConnectionListeners(conn);
this.readerRdy.addConnection(conn);
return conn.connect();
};
Reader.prototype.registerConnectionListeners = function(conn) {
conn.on(NSQDConnection.CONNECTED, (function(_this) {
return function() {
_this.debug(Reader.NSQD_CONNECTED);
return _this.emit(Reader.NSQD_CONNECTED, conn.nsqdHost, conn.nsqdPort);
};
})(this));
conn.on(NSQDConnection.ERROR, (function(_this) {
return function(err) {
_this.debug(Reader.ERROR);
_this.debug(err);
return _this.emit(Reader.ERROR, err);
};
})(this));
conn.on(NSQDConnection.CONNECTION_ERROR, (function(_this) {
return function(err) {
_this.debug(Reader.ERROR);
_this.debug(err);
return _this.emit(Reader.ERROR, err);
};
})(this));
conn.on(NSQDConnection.CLOSED, (function(_this) {
return function() {
var index;
_this.debug(Reader.NSQD_CLOSED);
index = _this.connectionIds.indexOf(conn.id());
if (index === -1) {
return;
}
_this.connectionIds.splice(index, 1);
return _this.emit(Reader.NSQD_CLOSED, conn.nsqdHost, conn.nsqdPort);
};
})(this));
return conn.on(NSQDConnection.MESSAGE, (function(_this) {
return function(message) {
return _this.handleMessage(message);
};
})(this));
};
Reader.prototype.handleMessage = function(message) {
return process.nextTick((function(_this) {
return function() {
var autoFinishMessage, numDiscardListeners, ref;
autoFinishMessage = (0 < (ref = _this.config.maxAttempts) && ref <= message.attempts);
numDiscardListeners = _this.listeners(Reader.DISCARD).length;
if (autoFinishMessage && numDiscardListeners > 0) {
_this.emit(Reader.DISCARD, message);
} else {
_this.emit(Reader.MESSAGE, message);
}
if (autoFinishMessage) {
return message.finish();
}
};
})(this));
};
return Reader;
})(EventEmitter);
module.exports = Reader;