We've been using a variation of the exception notification plugin since we deployed our application the first time two years ago and during this time we have fixed almost all bugs just by methodically reacting to every exception email. This plugin is a tremendous help in eliminating bugs! So now whenever we receive a new exception email, that means there is something tricky going on there. That exactly what happened to our production servers, when we misconfigured our DNS server and it took more that 15 seconds to send a single email.
AsyncMailer plugin to the rescue. The bulk of the plugin is below:
module AsyncMailer
%w(smtp sendmail).each do |type|
define_method("perform_delivery_async_#{type}") do |mail|
Thread.start do
send "perform_delivery_#{type}", mail
end
end
end
end
class ActionMailer::Base
include AsyncMailer
end
where we define two more delivery methods - async_smtp and async_sendmail. The only difference from standard delivery methods is that they are executed in parallel to the main execution and will not effect the ongoing database transaction. There is a chance that the email delivery might fail, but it is not as bad as a missing sale.
If you need to use something like this in your application, here is the link to the source of the plugin, which also includes some cleanup code in case of a process termination signal.
Also it's worth to look at a very nice backgroundrb plugin developed by Ezra Zygmuntowicz. In the future we are going to use it, when we have more long-running tasks to perform. Very great job!
Kent, thanks for this plugin and the steroids for debugging, Off Topic: PLease feel free to register your blog at RubyCorner.com, a meeting place for people interested in the Ruby Programming Language or any of the related technologies.
I've been looking for an easy solution like this but I was curious to know if this solves the problem of mongrel timeouts? Is it enough to just start another Thread or does mongrel want an entirely separate ruby instance?
The problem I've always had was BackgrounDRb server management. It would be nice to have something built into rails that handles the email asynchronously rather than having to add a separate server entirely (more monit entries!)
Thanks for the plugin!
I've just installed this and now all my emails come through with the sender as MAILER-DAEMON rather than the from that I created the mail with.