【问题标题】:Why is this code sending duplicate emails?为什么此代码会发送重复的电子邮件?
【发布时间】:2016-02-01 17:14:16
【问题描述】:

我们在 Azure 上运行一个调度程序,它每分钟运行一次,并检查数据库以查看需要为我们的应用发送哪些电子邮件并发送它们。

这在绝大多数情况下都有效,但有时,在几个小时内,调度程序会开始重复发送大多数电子邮件(最多 5 份)。

    query = "select id, email, textbody, htmlbody, subject from emailTable where sent = 0 AND DateSent IS NULL";
mssql.query(query, {
    success: function(results) {
        for(var i = 0 ; i < results.length; i++)
        {
            handleItem(results[i]);
        }
    },
    error: function(err) {
        console.log("Error : " + err);
    }
});

function handleItem(item) {
        sendMail(item); 
        var query = "update emailTable SET sent = 1, DateSent = GETDATE() where id = ?";
        mssql.query(query, [item.id]);

}

function sendMail(objMail)
{
    sendgrid.send({
      to:       objMail.email,
      from:     'source@sourcemail.com',
      fromname: "Source",
      subject:  objMail.subject,
      text:     objMail.textbody,
      html:     objMail.htmlbody
    }, function(err, json) {
      if (err) { return console.error(err); }
    });
}

当它开始失败时,就好像 handleItemsendMail 为同一个项目被多次调用。循环或解释这种行为的一般逻辑有什么问题吗?

【问题讨论】:

  • 是否有可能该任务可能需要超过一分钟,而另一个调度程序将开始运行并看到一些已由第一个调度程序排队的未发送电子邮件?我们使用 sendgrid,有时会出现导致电子邮件超时的网络故障。在这种情况下,发送一封电子邮件(失败)可能需要一整分钟......
  • 我们考虑过这一点,但根据我们的理解,Azure 应该将其限制为一次运行一个调度程序。此外,在查看日志时,我看到一个地址的每封重复邮件都同时发送,我认为如果它是一个新的调度程序启动,情况就不会如此。尽管如此,我还是会尝试测试调度程序的行为,看看我们的假设是否正确。
  • 您是否有任何数据库复制或任何可能导致您的数据暂时不同步的东西?
  • 您是否检查过哪个函数在循环中重复运行,handleItem()sendMail()?还是会查询重复项?

标签: node.js email azure sendgrid


【解决方案1】:
Try writing the update query in the callback function for sendMail(item)

eg. sendMail(item,function(){
 var query = "update emailTable SET sent = 1, DateSent = GETDATE() where id = ?";
        mssql.query(query, [item.id]);
});

function sendMail(objMail,cb)
{
    sendgrid.send({
      to:       objMail.email,
      from:     'source@sourcemail.com',
      fromname: "Source",
      subject:  objMail.subject,
      text:     objMail.textbody,
      html:     objMail.htmlbody
    }, function(err, json) {
      if (err) { cb(err) }
       cb(null,json)
    });
}

【讨论】:

  • 为什么这会解决重复问题?
  • 据我了解,您的 sendMail 在更新数据库之前会执行多次。
  • 这实际上比 OP 的代码更晚更新数据库。
猜你喜欢
  • 2018-04-29
  • 1970-01-01
  • 1970-01-01
  • 2013-06-22
  • 1970-01-01
  • 1970-01-01
  • 2012-05-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多