Created
February 20, 2009 14:43
-
-
Save hwatkins/67486 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
More Asynchronous Processing | |
Dave » 04 November 2008 » In Technology » | |
In a previous series on using workling and starling for asychronous processing, I described how to setup background tasks. Here is a quick way to use this for emails without a lot of changes to your application. | |
First, create lib/asynch_mail.rb: | |
# Makes an actionmailer class queue its emails into a workling queue | |
# instead of sending them sycnhronously | |
# | |
# From now on all MyMailer.deliver_whatever_email calls create an entry in | |
# the MailerWorker.deliver_mail corresponding queue and should be processed | |
# by a worker. If you still want to deliver mail sycnhronously add a bang to the method call: | |
# MyMailer.deliver_whatever_email! | |
# | |
module AsynchMail | |
def self.included(base) | |
base.class_eval do | |
class < < self | |
alias_method :orig_method_missing, :method_missing | |
# Catch deliver method calls to turn them into asynch calls | |
def method_missing(method_symbol, *parameters) | |
case method_symbol.id2name | |
when /^deliver_([_a-z]\w*)\!/ | |
orig_method_missing(method_symbol, *parameters) | |
when /^deliver_([_a-z]\w*)/ | |
mail = self.send("create_#{$1}", *parameters) | |
MailerWorker.asynch_deliver_mail(:class => self.name, :mail => mail) | |
else | |
orig_method_missing(method_symbol, *parameters) | |
end | |
end | |
end | |
end | |
end | |
end | |
Then, create app/workers/mailer_worker.rb: | |
class MailerWorker < Workling::Base | |
def deliver_mail(options) | |
Object.const_get(options[:class]).deliver(options[:mail]) | |
end | |
end | |
Now, all you need to do is include AsynchMail in your mailer class. | |
class MyMailer < ActionMailer::Base | |
include AsynchMail | |
end | |
That’s it! No other changes to all your mail calls are required. All will automatically become asynchronous. If your application sends a lot of emails, I recommend you do this. There is no reason to make your users wait for an email to be sent. | |
The only downside with this is that now emailing happens outside of Mongrel. This means that link_to does not have access to the HOST. As a result, you can can’t easily use the route helpers to generate urls. You will need to build your urls manually. At one point, I had some code that got around this, but it stopped working when I upgraded to Rails 2.x. In my app, it was easier to fix the urls than make the other work. If someone can provide this, it would great. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment