rsmq
Advanced tools
Comparing version 0.1.5 to 0.2.0
175
index.js
@@ -38,4 +38,8 @@ // Generated by CoffeeScript 1.6.2 | ||
this.redisns = redisns != null ? redisns : "rsmq"; | ||
this._initErrors = __bind(this._initErrors, this); | ||
this._handleError = __bind(this._handleError, this); | ||
this.sendMessage = __bind(this.sendMessage, this); | ||
this.receiveMessage = __bind(this.receiveMessage, this); | ||
this.listQueues = __bind(this.listQueues, this); | ||
this.getQueueAttributes = __bind(this.getQueueAttributes, this); | ||
this.deleteQueue = __bind(this.deleteQueue, this); | ||
@@ -49,2 +53,3 @@ this.deleteMessage = __bind(this.deleteMessage, this); | ||
this.initScript(); | ||
this._initErrors(); | ||
} | ||
@@ -61,7 +66,7 @@ | ||
if (err) { | ||
cb(err); | ||
_this._handleError(cb, err); | ||
return; | ||
} | ||
if (resp[0][0] === null || resp[0][1] === null || resp[0][2] === null) { | ||
cb("Queue not found"); | ||
_this._handleError(cb, "queueNotFound"); | ||
return; | ||
@@ -94,3 +99,3 @@ } | ||
if (err) { | ||
cb(err); | ||
_this._handleError(cb, err); | ||
return; | ||
@@ -100,3 +105,3 @@ } | ||
if (err) { | ||
cb(err); | ||
_handleError(cb, err); | ||
return; | ||
@@ -110,3 +115,3 @@ } | ||
RedisSMQ.prototype.createQueue = function(options, cb) { | ||
var mc, _ref, _ref1, _ref2, | ||
var _ref, _ref1, _ref2, | ||
_this = this; | ||
@@ -120,18 +125,26 @@ | ||
} | ||
mc = [["hsetnx", "" + this.redisns + options.qname + ":Q", "vt", options.vt], ["hsetnx", "" + this.redisns + options.qname + ":Q", "delay", options.delay], ["hsetnx", "" + this.redisns + options.qname + ":Q", "maxsize", options.maxsize]]; | ||
this.redis.multi(mc).exec(function(err, resp) { | ||
this.redis.time(function(err, resp) { | ||
var mc; | ||
if (err) { | ||
cb(err); | ||
_this._handleError(cb, err); | ||
return; | ||
} | ||
if (resp[0] === 0) { | ||
cb("Queue exists"); | ||
return; | ||
} | ||
_this.redis.sadd("" + _this.redisns + "QUEUES", options.qname, function(err, resp) { | ||
mc = [["hsetnx", "" + _this.redisns + options.qname + ":Q", "vt", options.vt], ["hsetnx", "" + _this.redisns + options.qname + ":Q", "delay", options.delay], ["hsetnx", "" + _this.redisns + options.qname + ":Q", "maxsize", options.maxsize], ["hsetnx", "" + _this.redisns + options.qname + ":Q", "created", resp[0]], ["hsetnx", "" + _this.redisns + options.qname + ":Q", "modified", resp[0]]]; | ||
_this.redis.multi(mc).exec(function(err, resp) { | ||
if (err) { | ||
cb(err); | ||
_this._handleError(cb, err); | ||
return; | ||
} | ||
cb(null, 1); | ||
if (resp[0] === 0) { | ||
_this._handleError(cb, "queueExists"); | ||
return; | ||
} | ||
_this.redis.sadd("" + _this.redisns + "QUEUES", options.qname, function(err, resp) { | ||
if (err) { | ||
_handleError(cb, err); | ||
return; | ||
} | ||
cb(null, 1); | ||
}); | ||
}); | ||
@@ -142,3 +155,4 @@ }); | ||
RedisSMQ.prototype.deleteMessage = function(options, cb) { | ||
var key, mc; | ||
var key, mc, | ||
_this = this; | ||
@@ -152,3 +166,3 @@ if (this._validate(options, ["qname", "id"], cb) === false) { | ||
if (err) { | ||
cb(err); | ||
_this._handleError(cb, err); | ||
return; | ||
@@ -165,3 +179,4 @@ } | ||
RedisSMQ.prototype.deleteQueue = function(options, cb) { | ||
var key, mc; | ||
var key, mc, | ||
_this = this; | ||
@@ -175,7 +190,7 @@ if (this._validate(options, ["qname"], cb) === false) { | ||
if (err) { | ||
cb(err); | ||
_this._handleError(cb, err); | ||
return; | ||
} | ||
if (resp[0] === 0) { | ||
cb("Queue not found"); | ||
_this._handleError(cb, "queueNotFound"); | ||
return; | ||
@@ -187,2 +202,41 @@ } | ||
RedisSMQ.prototype.getQueueAttributes = function(options, cb) { | ||
var key, | ||
_this = this; | ||
if (this._validate(options, ["qname"], cb) === false) { | ||
return; | ||
} | ||
key = "" + this.redisns + options.qname; | ||
this.redis.time(function(err, resp) { | ||
var mc; | ||
if (err) { | ||
_this._handleError(cb, err); | ||
return; | ||
} | ||
mc = [["hmget", "" + key + ":Q", "vt", "delay", "maxsize", "totalrecv", "totalsent", "created", "modified"], ["zcard", key], ["zcount", key, "-inf", resp[0] + "000"]]; | ||
_this.redis.multi(mc).exec(function(err, resp) { | ||
var o; | ||
if (err) { | ||
_this._handleError(cb, err); | ||
return; | ||
} | ||
o = { | ||
vt: parseInt(resp[0][0], 10), | ||
delay: parseInt(resp[0][1], 10), | ||
maxsize: parseInt(resp[0][2], 10), | ||
totalrecv: parseInt(resp[0][3], 10), | ||
totalsent: parseInt(resp[0][4], 10), | ||
created: parseInt(resp[0][5], 10), | ||
modified: parseInt(resp[0][6], 10), | ||
msgs: resp[1], | ||
hiddenmsgs: resp[2] | ||
}; | ||
cb(null, o); | ||
}); | ||
}); | ||
}; | ||
RedisSMQ.prototype.initScript = function(cb) { | ||
@@ -223,2 +277,14 @@ var script_changeMessageVisibility, script_receiveMessage, | ||
RedisSMQ.prototype.listQueues = function(cb) { | ||
var _this = this; | ||
this.redis.smembers("" + this.redisns + "QUEUES", function(err, resp) { | ||
if (err) { | ||
_this._handleError(cb, err); | ||
return; | ||
} | ||
cb(null, resp); | ||
}); | ||
}; | ||
RedisSMQ.prototype.receiveMessage = function(options, cb) { | ||
@@ -238,3 +304,3 @@ var _this = this; | ||
if (err) { | ||
cb(err); | ||
_this._handleError(cb, err); | ||
return; | ||
@@ -250,3 +316,3 @@ } | ||
if (err) { | ||
cb(err); | ||
_handleError(cb, err); | ||
return; | ||
@@ -280,3 +346,3 @@ } | ||
if (err) { | ||
cb(err); | ||
_this._handleError(cb, err); | ||
return; | ||
@@ -289,7 +355,7 @@ } | ||
if (typeof options.message !== "string") { | ||
cb("Message must be a string"); | ||
_this._handleError(cb, "messageNotString"); | ||
return; | ||
} | ||
if (options.message.length > q.maxsize) { | ||
cb("Message too long"); | ||
_this._handleError(cb, "messageTooLong"); | ||
return; | ||
@@ -300,3 +366,3 @@ } | ||
if (err) { | ||
cb(err); | ||
_handleError(cb, err); | ||
return; | ||
@@ -313,2 +379,29 @@ } | ||
RedisSMQ.prototype._handleError = function(cb, err, data) { | ||
var _err, _ref; | ||
if (data == null) { | ||
data = {}; | ||
} | ||
if (_.isString(err)) { | ||
_err = new Error(); | ||
_err.name = err; | ||
_err.message = ((_ref = this._ERRORS) != null ? typeof _ref[err] === "function" ? _ref[err](data) : void 0 : void 0) || "unkown"; | ||
} else { | ||
_err = err; | ||
} | ||
cb(_err); | ||
}; | ||
RedisSMQ.prototype._initErrors = function() { | ||
var key, msg, _ref; | ||
this._ERRORS = {}; | ||
_ref = this.ERRORS; | ||
for (key in _ref) { | ||
msg = _ref[key]; | ||
this._ERRORS[key] = _.template(msg); | ||
} | ||
}; | ||
RedisSMQ.prototype._VALID = { | ||
@@ -328,3 +421,5 @@ qname: /^([a-zA-Z0-9_-]){1,80}$/, | ||
if (!o[item]) { | ||
cb("No " + item + " supplied"); | ||
this._handleError(cb, "missingParameter", { | ||
item: item | ||
}); | ||
return false; | ||
@@ -334,3 +429,5 @@ } | ||
if (!this._VALID[item].test(o[item])) { | ||
cb("Invalid " + item + " format"); | ||
this._handleError(cb, "invalidFormat", { | ||
item: item | ||
}); | ||
return false; | ||
@@ -343,3 +440,7 @@ } | ||
if (_.isNaN(o[item]) || !_.isNumber(o[item]) || o[item] < 0 || o[item] > 9999999) { | ||
cb("" + item + " must be between 0 and 9999999"); | ||
this._handleError(cb, "invalidValue", { | ||
item: item, | ||
min: 0, | ||
max: 9999999 | ||
}); | ||
return false; | ||
@@ -351,3 +452,7 @@ } | ||
if (_.isNaN(o[item]) || !_.isNumber(o[item]) || o[item] < 1024 || o[item] > 65536) { | ||
cb("" + item + " must be between 1024 and 65536"); | ||
this._handleError(cb, "invalidValue", { | ||
item: item, | ||
min: 1024, | ||
max: 65536 | ||
}); | ||
return false; | ||
@@ -360,2 +465,12 @@ } | ||
RedisSMQ.prototype.ERRORS = { | ||
"missingParameter": "No <%= item %> supplied", | ||
"invalidFormat": "Invalid <%= item %> format", | ||
"invalidValue": "<%= item %> must be between <%= min %> and <%= max %>", | ||
"messageNotString": "Message must be a string", | ||
"messageTooLong": "Message too long", | ||
"queueNotFound": "Queue not found", | ||
"queueExists": "Queue exists" | ||
}; | ||
return RedisSMQ; | ||
@@ -362,0 +477,0 @@ |
{ | ||
"name": "rsmq", | ||
"description": "A really simple message queue based on Redis", | ||
"version": "0.1.5", | ||
"version": "0.2.0", | ||
"author": "P. Liess <smrchy+npm@gmail.com>", | ||
@@ -25,2 +25,4 @@ "engines": { | ||
"messagequeue", | ||
"sqs", | ||
"aws", | ||
"redis" | ||
@@ -27,0 +29,0 @@ ], |
@@ -24,5 +24,5 @@ # rsmq | ||
* Some AWS specific features are missing | ||
* Optional RESTful interface via [rest-rsmq](https://github.com/smrchy/rest-rsmq) | ||
## Usage | ||
@@ -189,3 +189,32 @@ | ||
### getQueueAttributes | ||
Get queue attributes, counter and stats | ||
Parameters: | ||
* `QueueName` (String): The Queue name. | ||
Returns: | ||
* `vt`: The visibility timeout for the queue in seconds | ||
* `delay`: The delay for new messages in seconds | ||
* `maxsize`: The maximum size of a message in bytes | ||
* `totalrecv`: Total number of messages received from the queue | ||
* `totalsent`: Total number of messages sent to the queue | ||
* `created`: Timestamp (epoch in seconds) when the queue was created | ||
* `modified`: Timestamp (epoch in seconds) when the queue was last modified with `setQueueAttributes` | ||
* `msgs`: Current number of messages in the queue | ||
* `hiddenmsgs`: Current number of hidden / not visible messages. A message can hidden while "in flight" due to a `vt` parameter or when sent with a `delay`. | ||
### listQueues | ||
List all queues | ||
Returns: | ||
* Array of queues (e.g. ["qname1", "qname2"]) | ||
### receiveMessage | ||
@@ -241,10 +270,4 @@ | ||
### getQueueAttributes | ||
Lists the queue parameters. | ||
### listQueues | ||
Lists all queues. | ||
### setQueueAttributes | ||
@@ -251,0 +274,0 @@ |
@@ -40,3 +40,3 @@ // Generated by CoffeeScript 1.6.2 | ||
should.exist(err); | ||
err.should.equal("Invalid qname format"); | ||
err.message.should.equal("Invalid qname format"); | ||
done(); | ||
@@ -50,3 +50,3 @@ }); | ||
should.exist(err); | ||
err.should.equal("Invalid qname format"); | ||
err.message.should.equal("Invalid qname format"); | ||
done(); | ||
@@ -61,3 +61,3 @@ }); | ||
should.exist(err); | ||
err.should.equal("vt must be between 0 and 9999999"); | ||
err.message.should.equal("vt must be between 0 and 9999999"); | ||
done(); | ||
@@ -72,3 +72,3 @@ }); | ||
should.exist(err); | ||
err.should.equal("vt must be between 0 and 9999999"); | ||
err.message.should.equal("vt must be between 0 and 9999999"); | ||
done(); | ||
@@ -83,3 +83,3 @@ }); | ||
should.exist(err); | ||
err.should.equal("vt must be between 0 and 9999999"); | ||
err.message.should.equal("vt must be between 0 and 9999999"); | ||
done(); | ||
@@ -94,3 +94,3 @@ }); | ||
should.exist(err); | ||
err.should.equal("delay must be between 0 and 9999999"); | ||
err.message.should.equal("delay must be between 0 and 9999999"); | ||
done(); | ||
@@ -105,3 +105,3 @@ }); | ||
should.exist(err); | ||
err.should.equal("delay must be between 0 and 9999999"); | ||
err.message.should.equal("delay must be between 0 and 9999999"); | ||
done(); | ||
@@ -116,3 +116,3 @@ }); | ||
should.exist(err); | ||
err.should.equal("delay must be between 0 and 9999999"); | ||
err.message.should.equal("delay must be between 0 and 9999999"); | ||
done(); | ||
@@ -127,3 +127,3 @@ }); | ||
should.exist(err); | ||
err.should.equal("maxsize must be between 1024 and 65536"); | ||
err.message.should.equal("maxsize must be between 1024 and 65536"); | ||
done(); | ||
@@ -138,3 +138,3 @@ }); | ||
should.exist(err); | ||
err.should.equal("maxsize must be between 1024 and 65536"); | ||
err.message.should.equal("maxsize must be between 1024 and 65536"); | ||
done(); | ||
@@ -149,3 +149,3 @@ }); | ||
should.exist(err); | ||
err.should.equal("maxsize must be between 1024 and 65536"); | ||
err.message.should.equal("maxsize must be between 1024 and 65536"); | ||
done(); | ||
@@ -160,6 +160,13 @@ }); | ||
should.exist(err); | ||
err.should.equal("maxsize must be between 1024 and 65536"); | ||
err.message.should.equal("maxsize must be between 1024 and 65536"); | ||
done(); | ||
}); | ||
}); | ||
it('ListQueues: Should return empty array', function(done) { | ||
rsmq.listQueues(function(err, resp) { | ||
should.not.exist(err); | ||
resp.length.should.equal(0); | ||
done(); | ||
}); | ||
}); | ||
it('Create a new queue: queue1', function(done) { | ||
@@ -179,9 +186,18 @@ rsmq.createQueue({ | ||
should.exist(err); | ||
err.should.equal("Queue exists"); | ||
err.message.should.equal("Queue exists"); | ||
done(); | ||
}); | ||
}); | ||
it('ListQueues: Should return array with one element', function(done) { | ||
rsmq.listQueues(function(err, resp) { | ||
should.not.exist(err); | ||
resp.length.should.equal(1); | ||
resp.should.include(queue1); | ||
done(); | ||
}); | ||
}); | ||
it('Create a new queue: queue2', function(done) { | ||
rsmq.createQueue({ | ||
qname: queue2 | ||
qname: queue2, | ||
maxsize: 2048 | ||
}, function(err, resp) { | ||
@@ -193,2 +209,11 @@ should.not.exist(err); | ||
}); | ||
it('ListQueues: Should return array with two elements', function(done) { | ||
rsmq.listQueues(function(err, resp) { | ||
should.not.exist(err); | ||
resp.length.should.equal(2); | ||
resp.should.include(queue1); | ||
resp.should.include(queue2); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
@@ -202,3 +227,3 @@ describe('Messages', function() { | ||
should.exist(err); | ||
err.should.equal("Queue not found"); | ||
err.message.should.equal("Queue not found"); | ||
done(); | ||
@@ -210,3 +235,3 @@ }); | ||
should.exist(err); | ||
err.should.equal("No qname supplied"); | ||
err.message.should.equal("No qname supplied"); | ||
done(); | ||
@@ -221,3 +246,3 @@ }); | ||
should.exist(err); | ||
err.should.equal("Message must be a string"); | ||
err.message.should.equal("Message must be a string"); | ||
done(); | ||
@@ -232,3 +257,3 @@ }); | ||
should.exist(err); | ||
err.should.equal("Message must be a string"); | ||
err.message.should.equal("Message must be a string"); | ||
done(); | ||
@@ -359,3 +384,3 @@ }); | ||
}, function(err, resp) { | ||
err.should.equal("No id supplied"); | ||
err.message.should.equal("No id supplied"); | ||
done(); | ||
@@ -369,3 +394,3 @@ }); | ||
}, function(err, resp) { | ||
err.should.equal("Invalid id format"); | ||
err.message.should.equal("Invalid id format"); | ||
done(); | ||
@@ -415,3 +440,3 @@ }); | ||
should.not.exist(resp); | ||
err.should.equal("Message too long"); | ||
err.message.should.equal("Message too long"); | ||
done(); | ||
@@ -493,3 +518,3 @@ }); | ||
}); | ||
return it('Receive a message from queue2. Should return {}', function(done) { | ||
it('Receive a message from queue2. Should return {}', function(done) { | ||
rsmq.receiveMessage({ | ||
@@ -502,2 +527,13 @@ qname: queue2 | ||
}); | ||
return it('GetQueueAttributes: Should return queue attributes', function(done) { | ||
rsmq.getQueueAttributes({ | ||
qname: queue2 | ||
}, function(err, resp) { | ||
should.not.exist(err); | ||
resp.totalrecv.should.equal(1500); | ||
resp.totalsent.should.equal(1000); | ||
resp.msgs.should.equal(0); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
@@ -504,0 +540,0 @@ describe('CLEANUP', function() { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
63848
932
286