How to use multi-threading in rails 3?
Solution 1
There basically two ways to wrap your loop in order to get "multi-threading":
-
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)
-
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.
Related videos on Youtube
anil.n
Updated on June 04, 2022Comments
-
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 MazorI'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 over 12 yearsWill try this in my application.
-
laffuste almost 10 yearsWhen 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).