Ruby on rails Rails 4:如何在单独的线程中发送邮件?

Ruby on rails Rails 4:如何在单独的线程中发送邮件?,ruby-on-rails,multithreading,email,ruby-on-rails-4,Ruby On Rails,Multithreading,Email,Ruby On Rails 4,我有一个应用程序,需要偶尔发送电子邮件爆炸到整个用户群时,管理员做了一些事情。这很好,但是当有很多用户时,管理员的页面将等待所有邮件发送,这是不可取的 为了缓解这种情况,我尝试使用新的线程发送电子邮件: t = Thread.new do User.all.each do |user| Mailer.email(user).deliver end end at_exit{ t.join } 这很好,但在我的测试套件中,我无法测试以确保电子邮件发送工作正常: # This tes

我有一个应用程序,需要偶尔发送电子邮件爆炸到整个用户群时,管理员做了一些事情。这很好,但是当有很多用户时,管理员的页面将等待所有邮件发送,这是不可取的

为了缓解这种情况,我尝试使用新的线程发送电子邮件:

t = Thread.new do
  User.all.each do |user|
    Mailer.email(user).deliver
  end
end
at_exit{ t.join }
这很好,但在我的测试套件中,我无法测试以确保电子邮件发送工作正常:

# This test now fails with the new Thread above
test "admin action should send email blast" do
  assert_difference("ActionMailer::Base.deliveries.count", User.count) do
    post :action
  end
end
因此,我的问题是:

  • 此方法是在新线程中发送电子邮件的最佳方式吗?或者有没有一个gem可以处理这种交互
  • 如果发送是在新线程中完成的,我如何测试电子邮件是否在我的测试套件中发送?是否有方法检查等待所有线程完成
    在不同线程中发送电子邮件的最佳方法是使用延迟作业或类似的gem

    使用延迟作业gem,您还可以在计划的时间在不同的线程中发送电子邮件或执行其他操作

    另一个选项是使用sidekiq,安装sidekiq gem并将这一行添加到application.rb文件中

    config.active_job.queue_adapter = :sidekiq
    

    对于异步任务,我更喜欢使用基于队列的方法。[Delayed job]()是一个选项,但我更喜欢使用[sidekiq]()


    [此处]()是使用sidekiq异步发送电子邮件的示例

    在rails 4.2中,有一个处理作业的特殊类称为active job,它允许您将长任务排队等待另一个进程在后台处理这些任务,还可以将任务排队一段时间,例如“明天上午8点发送此电子邮件”

    要处理这些队列,您需要选择一个后端来处理它们,下面是一个

    每种方法都有其优缺点,例如sidekiq是一个多线程处理程序,因此它使用较低的内存,而例如Stuck punch使用与主服务器相同的线程,因此它使用的内存要少得多,适用于内存较低的服务器无法处理第二个ruby线程的情况


    至于测试部分,已经解释了如何测试您的电子邮件,以及测试电子邮件是否排队,测试呈现的模板是否正确,以及其中是否包含正确的文本。

    我认为您希望异步发送邮件,因为您可能会使用许多gem,比如延迟作业,sidekiq等。我个人建议使用sidekiq,因为它速度更快,并且在后台使用了内存数据库中的Redis

    Rails 4.2引入了活动作业,因此使用它的优点是,您可以随时从一个排队系统切换到另一个排队系统而不必担心,并且您可以指定yiu想要的机器

    module YourApp
     class Application < Rails::Application
      # Be sure to have the adapter's gem in your Gemfile
      # and follow the adapter's specific installation
      # and deployment instructions.
      config.active_job.queue_adapter = :sidekiq
     end
    end
    
    moduleyourapp
    类应用程序
    1。我只是将发送电子邮件逻辑提取到一个单独的方法中,然后进行测试。2.通过调用
    Thread.join
    方法或在您的情况下调用
    t.join