如何在导轨3中使用多线程?

ani*_*l.n 14 multithreading actionmailer postmark ruby-on-rails-3

我使用动作邮件通过邮戳向用户发送邮件.这是我在控制器中的代码:

@users = User.where(some condition)
@product = Product.find_by_name(some name).first
for user in @users
  UserMailer.new_product_arrival(user, @product, home_url).deliver
end
Run Code Online (Sandbox Code Playgroud)

这是我的user_mailer.rb

def new_product_arrival(user,product,home_url)
  @from         = Settings.mailer_from_address
  @recipients   = user.login
  @sent_on      = Time.now
  @user = user
  @product = product
  @content_type = "text/html"
  @home_url = home_url
end
Run Code Online (Sandbox Code Playgroud)

问题是,如果有超过10个用户,由于for循环需要很长时间.我需要知道我们是否可以通过使用多线程或后台作业来处理这个问题.我不想使用后台工作,但任何人都可以告诉我如何使用多线程实现上述功能.

我使用ruby 1.8.7和rails 3.0.7

kri*_*ard 20

基本上有两种方法来包装循环以获得"多线程":

  1. 为每个交付spwan一个线程并将它们连接回主线程

    threads = []
    for user in @users
       threads << Thread.new do
         UserMailer.new_product_arrival(user, @product, home_url).deliver
       end
    end
    threads.each(&:join)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 分叉整个rails应用程序(非常混乱,但服务请求的rails应用程序将立即响应)并将进程分离:

    process = fork do
      for user in @users
        UserMailer.new_product_arrival(user, @product, home_url).deliver
      end
      Process.kill("HUP") 
      #sends the kill signal to current Process, which is the Rails App sending your emails 
    end
    Process.detach(process)
    
    Run Code Online (Sandbox Code Playgroud)

希望有所帮助

  • 使用线程时,您可能希望在Thread块的末尾添加:`ActiveRecord :: Base.connection.close`(如果线程有DB调用,它们应该在您的示例中有). (3认同)