【问题标题】:How to use multi-threading in rails 3?如何在 Rails 3 中使用多线程?
【发布时间】:2012-01-04 01:03:39
【问题描述】:

我正在通过邮戳使用 actionmailer 向用户发送邮件。这是我在控制器中的代码:

@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

这是我的 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

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

我正在使用 ruby​​ 1.8.7 和 rails 3.0.7

【问题讨论】:

  • 我还不是 ruby​​ 专家(目前),但邮戳确实支持发送批量电子邮件,所以如果您要向一大群用户发送电子邮件,那么使用它可能更容易而不是每个人的 api 调用。

标签: multithreading ruby-on-rails-3 actionmailer postmark


【解决方案1】:

为了获得“多线程”,基本上有两种包装循环的方法:

  1. 为每次交付创建一个线程并将它们加入主线程

    threads = []
    for user in @users
       threads << Thread.new do
         UserMailer.new_product_arrival(user, @product, home_url).deliver
       end
    end
    threads.each(&:join)
    
  2. fork 整个 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)
    

希望有帮助

【讨论】:

  • 将在我的应用程序中尝试这个。
  • 使用线程时,您可能希望在 Thread 块的末尾添加:ActiveRecord::Base.connection.close(如果线程有 DB 调用,它们在您的示例中应该有)。
【解决方案2】:

我们的开发者Artem 最近对Postmark gem 进行了重大更新

这使您可以轻松地批量发送电子邮件,这应该可以让您更快地发送电子邮件。看看吧。

【讨论】:

    【解决方案3】:

    试试delayed_job 宝石。这是一个基于数据库的后台作业 gem。我们在一个电子商务网站中使用它,例如向用户发送订单确认电子邮件。

    这些任务可以在后台异步发生,因为您的 Rails 应用不需要 他们立即执行。

    【讨论】:

    • “我不想使用后台作业”-OP
    【解决方案4】:

    嗯,我是来自肯尼亚内罗毕开发学校的 Rails 学生..我认为您可以尝试一下,..soo 您所遇到的是由于用户数量而导致响应延迟..您可以尝试长轮询一个例子

    poll = function (){
      s.ajax{
           url:/'chat.json'
           data: { last_time: get last_time () }
         }}.done(function(data) {
         // handle data
         setTimeout(poll,1000);
         });
    }
    

    以您的方式尝试 ..这对于实时应用程序很有用..o 您甚至可以使用动作控制器:: live ..我认为您对使用 rails 进行线程很熟悉 .also .上述示例会帮助您,,希望 \

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-06
      • 2011-06-21
      • 1970-01-01
      • 2016-12-01
      • 2020-12-28
      • 2021-08-04
      相关资源
      最近更新 更多