node-amqp-connection-manager icon indicating copy to clipboard operation
node-amqp-connection-manager copied to clipboard

How to use createChannel with callback

Open brecke opened this issue 8 years ago • 5 comments

Hi there,

I'm trying to use this lib but I still use callbacks in the project I'm currently working on, and I can't get to use the callback version of createChannel. Is there an example I can look at?

brecke avatar Oct 20 '17 15:10 brecke

Here's a quick stab at rewriting the example from the README using callbacks:

var amqp = require('amqp-connection-manager');

// Create a new connection manager
var connection = amqp.connect(['amqp://localhost']);

// Ask the connection manager for a ChannelWrapper.  Specify a setup function to run every time we reconnect
// to the broker.
var channelWrapper = connection.createChannel({
    json: true,
    setup: function(channel) {
        // `channel` here is a regular amqplib `ConfirmChannel`.
        return channel.assertQueue('rxQueueName', {durable: true});
    }
});

// Send some messages to the queue.  If we're not currently connected, these will be queued up in memory
// until we connect.  Note that `sendToQueue()` and `publish()` return a Promise which is fulfilled or rejected
// when the message is actually sent (or not sent.)
channelWrapper.sendToQueue('rxQueueName', {hello: 'world'}, (err, done) => {
    if(err) {
        return console.log("Message was rejected...  Boo!");
        return;
    }
    console.log("Message was sent!  Hooray!");
});

And the setup example:

function setupFn(channel, done) {
    channel.assertQueue("my-queue",  { exclusive: true, autoDelete: true }, err => {
        if(err) {return done(err);}
        channel.bindQueue("my-queue", "my-exchange", "create", err => {
            if(err) {return done(err);}
            channel.consume("my-queue", handleMessage, done);
        });
    });
};
channelWrapper.addSetup(setupFn, err => {
    if(err) {console.log("Error adding setup function");}
});

I just realized there's actually a bug, and this won't quite work correctly if there's a setup function that takes a callback and the channel is already connected. I'll fix this first thing tomorrow. :)

jwalton avatar Oct 22 '17 15:10 jwalton

Hi,

Thanks for the information, it makes a lot more sense now. I'll try it in my code as soon as you fix that bug.

I was also getting another problem which was not being able to call the channel methods with a callback as the last parameter - only the promised based api works - that might be related to that somehow? Or maybe not, I don't know. The code just stalled if I tried to use the callback api.

brecke avatar Oct 23 '17 08:10 brecke

Fixed in 1.3.6. I also added a callback-based test case for publish(). One thing about using callbacks - you need to specify the options parameter, even if you have no options:

channelWrapper.publish('exchange', 'routingKey', 'message', {}, (err, result) => {...})

jwalton avatar Oct 23 '17 15:10 jwalton

There's something not quite right though.. for instance, when I try to do this:

channel.assertExchange(exchangeName, exchangeOptions.type, exchangeOptions, function(err, exchange) {

It stalls. but if I try to do this instead (promises):

channel.assertExchange(exchangeName, exchangeOptions.type, exchangeOptions).then((ok) => {

It runs okay. There must be something I'm missing when using callbacks.

For the examples above, I'm following amqplib documentation and using the channel object - not the channelWrapper provided by node-amqp-connection-manager.

If I were using amqplib directly I'd be using require('amqplib/callback_api') but it's like I can't access the amqplib callback API through requiring node-amqp-connection-manager. Does this make sense? This also applies to other amqplib methods.

brecke avatar Oct 26 '17 12:10 brecke

same here. The callback of assertQueue() in your given example is never called.

rolatsch avatar Dec 14 '17 15:12 rolatsch