Anders Östman
Anders Östman

Reputation: 3832

Sending multiple mail in Nodejs

A web app I'm building will send out invoices to clients every third month. This will be a scheduled event that is run in the middle of the night, but under development I have put this code into a route so I can test it.

In short i want the code to do the following.

  1. QUery all unsent invoices from DB.
  2. Make a call to Mandrill for each invoice (In this call I'm also invoking a function creating a Mandrill message object from the invoice).
  3. For every message Mandrill send, Update the DB invoice sent: true.
  4. When all invoices are sent, make a final callback in the async.waterfall

The code below works. but i have some concerns regarding the _.each.

invoices.post('/invoices/send/', function(req, res, next) {

    async.waterfall([
        // Query all unsent invoices
        function(callback) {
            db.invoices.find({sent: false}).toArray(callback);
        },

        // Send all unsent invoices
        function(invoices, callback) {
            if (invoices.length === 0) {
                var err = new Error('There are no unsent invoices');
                err.status = 400;
                return next(err); //Quick escape if there are no matching invoice to process
            }

            // Make a call to Mandrill transactional email service for every invoice. 
            _.each(invoices, function(invoice) {
                mandrillClient.messages.sendTemplate({template_name: "planpal-invoice", template_content: null, message: mandrillClient.createInvoiceMessage(invoice)}, function(sendResult) {
                    console.log(sendResult);
                    db.invoices.updateById(invoice._id, {$set: {sent: true}}, function(err, saveResult) {
                        console.log(saveResult);
                    });
                }, function(err) {
                    return next(err);
                });
            });

            callback(null, 'done');
        }
    ],
    function(err, result) {
        if (err) {
            return next(err);
        }
        res.json(result);
    });
});

I'm thinking I should use async.eachLimit instead.... but I dont know how to write it. I have no idea what i should set the limit to, but I guess several parallel request would be better than running all mandrill request in serie like above, am I wrong? EDIT _.each run the callbacks in parallel. The difference from a async.each is that I dont get a "final callback"

Conclusion: Should i use a async.eachLimit above? If Yes, what is a good limit value?

Upvotes: 0

Views: 1116

Answers (1)

vodolaz095
vodolaz095

Reputation: 6986

I think you can use the https://github.com/caolan/async#each function.

it will execute the queries in parallel too

Upvotes: 1

Related Questions