How to use multi-threading in rails 3?

10,463

Solution 1

There basically two ways to wrap your loop in order to get "multi-threading":

  1. Spwan a thread for each delivery and join them back to the main thread

    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 over the entire rails app ( pretty messy but the rails app serving the request will respond immediately ) and have the process detached:

    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)
    

Hope that helps

Solution 2

our developer Artem recently made a major update to the Postmark gem

which allows you to send emails easily in batches, which should allow you to send emails faster. Check it out.

Share:
10,463

Related videos on Youtube

anil.n
Author by

anil.n

Updated on June 04, 2022

Comments

  • anil.n
    anil.n almost 2 years

    I am sending mail to the users using actionmailer through postmark. This is my code in controller:

    @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
    

    and this my 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
    

    The problem is that if there are more than 10 users it takes a very long time because of the for loop. I need to know if we can handle this by using multi-threading or background job. I don't want to use background job, but can anyone tell me how to implement the above using multi-threading.

    I am using ruby 1.8.7 and rails 3.0.7

    • Oren Mazor
      Oren Mazor
      I'm not at all a ruby expert (yet) but postmark does support sending batch emails, so if you're emailing a large group of users, it might be easier for you to use that rather than an api call for each one.
  • anil.n
    anil.n over 12 years
    Will try this in my application.
  • laffuste
    laffuste almost 10 years
    When using threads you might want to add at the end of the Thread block: ActiveRecord::Base.connection.close (if the threads have DB calls, which they should have in your example).