I can publish a message to a deleted exchange and queue, it does not throw an error, the operation seems successful.
harunkelesoglu opened this issue · 3 comments
Hello,
I wanted to try the library before implementing it in their own services. I wanted to check if the queues and exchanges would be recreated when I delete them.
When I try to send a message to a deleted exchange, it does not throw an error, the operation seems successful. There is no exchange but publication emit success like below
My code block like below
index.js
const Broker = require('rascal').BrokerAsPromised;
const config = require('./config.json');
async function publishMessage(broker,message){
setInterval(async function(){
const publication = await broker.publish('demo_pub', message);
publication.on('success', async function(messageId){
console.log(messageId);
});
publication.on('error', async function(err){
console.log(err);
});
}, 5000)
}
async function consumeMessage(broker){
let counter = 0;
const subscription = await broker.subscribe('demo_sub', 'b1');
subscription
.on('message', (message, content, ackOrNack) => {
counter++;
console.log(counter,content);
ackOrNack();
})
.on('error', async function(err){
console.log(err);
});
}
(async () => {
try {
const broker = await Broker.create(config);
broker.on('error', ({ vhost, connectionUrl }) => {
console.log('RabbitMQ broker creation error', err, vhost, connectionUrl)
});
// Publish a message
await publishMessage(broker,'Harun KELEŞOĞLU');
} catch (err) {
console.error(err);
}
})();
(async () => {
try {
const broker = await Broker.create(config);
broker.on('error', ({vhost, connectionUrl})=>{
console.log('RabbitMQ broker creation error', err, vhost, connectionUrl)
});
// Consume a message
await consumeMessage(broker);
} catch (err) {
console.error(err);
}
})();
config.json
{
"vhosts": {
"tasks": {
"namespace": false,
"connection": {
"url": "amqp://harun:keles0glu_@localhost:5672/tasks"
},
"exchanges": {
"tasks_ex":{
"assert": true,
"type": "direct"
}
},
"queues": {
"tasks_q": {
}
},
"bindings": {
"b1":{
"source": "tasks_ex",
"destination": "tasks_q",
"destinationType": "queue",
"bindingKey":"tasks_route"
}
},
"publications": {
"demo_pub": {
"vhost":"tasks",
"exchange": "tasks_ex",
"routingKey": "tasks_route",
"confirm": false
}
},
"subscriptions": {
"demo_sub": {
"queue": "tasks_q",
"prefetch": 1
}
}
}
}
}
Ok, Probably publication confirm config setting must be true. Like below.
But ı want to recreate if exhange deleted. How can i do that.
{
"vhosts": {
....
"publications": {
"demo_pub": {
"vhost":"tasks",
"exchange": "tasks_ex",
"routingKey": "tasks_route",
"confirm": true
}}
...
}
Hi @harunkelesoglu,
You're correct, without the confirm option, AMQP is fire and forget. The underlying client (amqplib) doesn't even offer a callback when publishing using a confirm channel, so there's no option except to emit a success event if rascal's API is to remain channel agnostic.
Regarding your next question - how to recreate the exchange?
The short but IMHO wrong answer is you could shutdown and restart your application, or if you can safely do so without shutting down the rest of your application, then restart the broker. Rascal does have a "bounce" function which I added for test purposes which should do this. Of course restarting even just the broker could be highly disruptive for your workflow.
The longer answer is more a philosophical one. If you are working in an environment where there is a reasonable chance of someone deleting an exchange, then this is what I would focus on fixing instead of adding complexity to my application. Furthermore, a rogue RabbitMQ admin could also delete queues, bindings, users and even vhosts, not all of which are recoverable using AMQP. They could even manually recreate the exchange with different options, preventing it being re-asserted. Consequently, you would be putting in a lot of effort without actually mitigating the risk.
Therefore my recommendation (without knowing your specific use case), is to ignore this possibility, ensure only people who are trustworthy have access, and add monitoring which tells your application stops behaving as expected.
Thanks @cressie176 for you great response. I will ignore this possibility :D. Maybe I should tell the qa team not to delete it while testing :D Thanks a lot again.