Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'unsubscribe' of https://github.com/squaremo/node-amqp i…

…nto unsub
  • Loading branch information...
commit 0b6d0635cb03b4b67b3f52e0c9cd7eda9c0d5464 2 parents 964856c + e6192b5
@postwait postwait authored
Showing with 60 additions and 2 deletions.
  1. +20 −0 README.md
  2. +13 −2 amqp.js
  3. +27 −0 test/test-unsubscribe.js
View
20 README.md
@@ -188,6 +188,26 @@ Look at the source code if you need to do this.
This method will emit 'basicConsumeOk' when ready.
+### queue.unsubscribe(consumerTag)
+
+Unsubscribe from a queue, given the consumer tag. The consumer tag is
+supplied to the *promise callback* of `Queue.subscribeRaw` or
+`Queue.subscribe`:
+
+ connection.queue('foo', function(queue) {
+ var ctag;
+ queue.subscribe(function(msg) {...})
+ .addCallback(function(ok) { ctag = ok.consumerTag; });
+ // ... and in some other callback
+ queue.unsubscribe(ctag);
+ });
+
+Note that `Queue.unsubscribe` will not requeue messages that have not
+been acknowledged. You need to close the queue or connection for that
+to happen. You may also receive messages after calling `unsubscribe`;
+you will **not** receive messages from the queue after the unsubscribe
+promise callback has been invoked, however.
+
### queue.shift()
For use with `subscribe({ack: true}, fn)`. Acknowledges the last
View
15 amqp.js
@@ -1349,7 +1349,7 @@ Channel.prototype._handleTaskReply = function (channel, method, args) {
if (this._tasks[i].reply == method) {
task = this._tasks[i];
this._tasks.splice(i, 1);
- task.promise.emitSuccess();
+ task.promise.emitSuccess(args);
this._tasksFlush();
return true;
}
@@ -1425,6 +1425,18 @@ Queue.prototype.subscribeRaw = function (/* options, messageListener */) {
});
};
+Queue.prototype.unsubscribe = function(consumerTag) {
+ var self = this;
+ return this._taskPush(methods.basicCancelOk, function () {
+ self.connection._sendMethod(self.channel, methods.basicCancel,
+ { reserved1: 0,
+ consumerTag: consumerTag,
+ noWait: false });
+ })
+ .addCallback(function () {
+ delete self.consumerTagListeners[consumerTag];
+ });
+};
Queue.prototype.subscribe = function (/* options, messageListener */) {
var self = this;
@@ -1514,7 +1526,6 @@ Queue.prototype.subscribe = function (/* options, messageListener */) {
};
Queue.prototype.subscribeJSON = Queue.prototype.subscribe;
-
/* Acknowledges the last message */
Queue.prototype.shift = function () {
if (this._lastMessage) {
View
27 test/test-unsubscribe.js
@@ -0,0 +1,27 @@
+require('./harness');
+
+var queueName = 'node-unsubscribe-test';
+var counter = 0;
+
+connection.on('ready', function() {
+ var ex = connection.exchange('');
+ var q = connection.queue(queueName, {autoDelete: false}, function() {
+ ex.publish(queueName, {"msg": 'Message1'});
+ var defr = q.subscribe(function() { counter += 1; });
+ defr.addCallback(function(ok) {
+ // NB there is a race here, since the publish above and this
+ // unsubscribe are sent over different channels.
+ var defr2 = q.unsubscribe(ok.consumerTag);
+ defr2.addCallback(function() {
+ connection.publish(queueName, {"msg": 'Message2'});
+ // alas I cannot think of a way to synchronise on the queue
+ setTimeout(function() { q.destroy().addCallback(function() {
+ connection.end(); })}, 500);
+ });
+ });
+ });
+});
+
+process.addListener('exit', function() {
+ assert.equal(1, counter);
+});
Please sign in to comment.
Something went wrong with that request. Please try again.