How to use multi-threading in rails 3?
-
06-03-2021 - |
Question
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
Solution
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
OTHER TIPS
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.
Try delayed_job gem. This is a database-based background job gem. We used it in an e-commerce website, for example, sending order confirmation emails to users.
These tasks can happen asynchronously in the background, because your Rails app doesn't need them executed immediately.
um im a rails student from nairobi dev school kenya ..and i think you can give this a try ,..soo what you are having there is the delayed response due to the number of users ..you can try long polling an example
poll = function (){
s.ajax{
url:/'chat.json'
data: { last_time: get last_time () }
}}.done(function(data) {
// handle data
setTimeout(poll,1000);
});
}
try that in your ow way ..this is useful for a real time application..o you can use even action controller:: live ..i think youre farmiliar with threading with rails .also .the above exmples will hep you ,,hopefuly \