squaremo/rabbit.js

Ability to specify queue arguments

Opened this issue · 4 comments

Is it be possible to specify queue arguments for a REQ socket? I need to send a message to a queue that has a dead letter exchange. When I try to connect the socket I get the following error:

Error: Channel closed by server: 406 (PRECONDITION-FAILED) with message "PRECONDITION_FAILED - inequivalent arg 'x-dead-letter-exchange' for queue 'myqueue' in vhost '/': received none but current is the value 'DeadLetterExchange' of type 'longstr'"
at Channel.C.accept (/Users/etyrrill/mgmt-code/ui/build/node_modules/rabbit.js/node_modules/amqplib/lib/channel.js:398:24)

amqplib supports dead letter exchanges, but I couldn't figure out how to pass those parameters into rabbit.js so it can pass the parameters down to amqplib.

Ah I see, you created the queue with a dead-letter exchange already (through the management UI perhaps?), then because rabbit.js doesn't know this and can't be told, it falls over. What a pain!

I would really like to keep the interface to rabbit.js as simple as possible, which is why I don't expose those kinds of options. But I can see this is a major pain for you. Maybe I could check for the queue first, and leave it alone if it exists already.

As a workaround for now, you could use a policy to set the dead letter exchange for the queue; I've tried this, and it seems that queue attributes that come from policies don't count when it comes to checking for inequivalent args (as the error above has it).

Checking for the queue first would be a great solution. I considered making that change instead of exposing the deadLetterExchange option (see pull request #98), but being lazy, I made the easy change instead. The queue is created by the consumer, and will always be there before our node server starts.

I appreciate you taking a look at this.

Thanks,
Ed

I have pushed a change to master which lets you tell a socket not to try and create objects when connecting; this means you can use exchanges and queues created elsewhere with properties different to those rabbit.js would give them.

var ctx = require('rabbit.js').createContext();
var push = ctx.socket('PUSH', {noCreate: true});
push.connect(existingQueue);

I figure this is a solution to the general problem of using existing objects. Would you let me know if it works for you? If so I will tidy it up and make it a lasting change to the API. Thanks!

@squaremo how would you subscribe and consume an existing queue?