rabbit.js
rabbit.js copied to clipboard
Durable topic exchange
I need to be able to publish to a durable topic exchange but at the moment this seems to be disallowed as per
PubSocket.prototype.connect = function(destination, callback) {
var self = this, ch = this.ch;
ch.assertExchange(destination,
this.options.routing || 'fanout',
{durable: false, autoDelete: false})
.then(function(ok) {
self.pubs.push(destination);
}).then(callback);
};
When I connect to RabbitMQ I get the following error
Channel closed by server: 406 (PRECONDITION-FAILED) with message
"PRECONDITION_FAILED - cannot redeclare exchange 'ExchangeName'
in vhost '/' with different type, durable, internal or autodelete value"
It would be great if it were possible to do the following:
var pub = context.socket('PUBLISH', {routing: 'topic', persistent: true});
pub.connect(exchange);
I ended up updating the assertExchange
code above to set durable
to true
but I'm not sure what the wider implications are of doing so.
I'm happy to submit a pull request if this is a feasible option.
Is that because you are using it from another library?
@squaremo it's because the consumers are actually different applications/services.
Right. And those other applications need it to be durable, so e.g., bindings don't go away.
I suppose it would make sense if a "persistent" PUBLISH socket declared its exchanges as durable. Does it belong in the socket constructor or connect
though? It could be both.
I thought it might make sense to appear in connect
but noticed that in other places you allowed for the persistent
option in the constructor. I guess it's really a matter of whether you conform to the current method of passing an option in the constructor or whether it makes more sense to allow for a durable flag in connect
.
The constructor arguments tend to just set the default for that socket, so I guess it can be in both places.
+1 For the current version of our application we will simply leave everything 'transient' but this could be of interest in the future.
To my knowledge connecting/re-asserting an exchange with different properties than the already existing one fails (in this case durable and transient). Is it possible to read out the properties of an exchange before connecting to it? Wouldn't this allow some kind of auto-fix/step-up-down option/function or even auto-configuration of the socket, or is my imagination simply going wild again ..
+1 I am currently trying to work around this but I would definitely appreciate control over the exchange's properties.
+1 Currently using default "amq.topic" exchange from RabbitMQ which is durable.
+1 here as well.
OK. Sorry for the long silence. 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 pub = ctx.socket('PUB', {noCreate: true});
pub.connect(existingExchange);
If anyone is game to try this out, would you let me know if it works for you? It's pretty sketchy but I'd like to build on it. Thank you!
Thanks! This works for me with "rabbit.js": "^0.4.4",
context.socket('PUB', {noCreate: true});
for a durable exchange that already existed on my server: