views:

1047

answers:

4

Hi guys,

I've been sending emails on my application (ruby 1.8.7, rails 2.3.2) like this Thread.new{UserMailer.deliver_signup_notification(user)}

Since ruby use green threads, there's any performance advantage doing this, or I can just use UserMailer.deliver_signup_notification(user) ?

Thanks

+1  A: 

They'll be the same as far as I know.

Brian
+2  A: 

In general, using green threads to run background tasks asynchronously will mean that your application can respond to the user before the mail is sent. You're not concerned about exploiting multiple CPUs; you're only concerned on off-loading the work onto a background process and returning a web page as soon as possible.

And from examining the Rails documentation, it looks like deliver_signup_notification will block long enough to get the mail queued (although I may be wrong). So using a thread here might make your application seem more responsive, depending on how your mailer is configured.

Unfortunately, it's not clear to me that deliver_signup_notification is necessarily thread-safe. I'd want to read the documentation carefully before relying on that.

Note also that you're making assumptions about the lifetime of a Rails process once a request has been served. Many Rails applications using DRb (or a similar tool) to offload these background tasks onto an entirely separate worker process. The easiest way to do this changes fairly often--see Google for a number of popular libraries.

emk
+3  A: 

Global VM lock will still almost certainly apply while sending that email, meaning no difference.

You should not start threads in a request/response cycle. You should not start threads at all unless you can watch them from create to join, and even then, it is rarely worth the trouble it creates.

Rails is not thread-safe, and is not meant to be from within your controller actions. Only since Rails 2.3 has just dispatching been thread-safe, and only if you turn it on in environment.rb with config.threadsafe!.

This article explains in more detail. If you want to send your message asynchronously use BackgroundRb or its analog.

Sam C
+1  A: 

I have used your exact strategy and our applications are currently running in production (but rails 2.2.2). I've kept a close eye on it and our load has been relatively low (Less than 20 emails sent per day average, with peaks of around 150/day).

So far we have noticed no problems, and this appears to have resolved several performance issues we were having when using Google's mailserver.

If you need something in a hurry then give it a shot, it has been working for us.

Gdeglin