diff options
author | Brian Cardarella <bcardarella@gmail.com> | 2012-06-23 14:36:09 -0400 |
---|---|---|
committer | Brian Cardarella <bcardarella@gmail.com> | 2012-06-23 14:36:09 -0400 |
commit | dc7fd821dca0b2088bde7e0a2a06bfe59e1ba5c6 (patch) | |
tree | bf317b8bc64a1842aa3c5e65b3f829e1f2eaa9f1 /actionmailer | |
parent | 3726080ecea8b34edeac37f358e8dd050cbb00cb (diff) | |
download | rails-dc7fd821dca0b2088bde7e0a2a06bfe59e1ba5c6.tar.gz rails-dc7fd821dca0b2088bde7e0a2a06bfe59e1ba5c6.tar.bz2 rails-dc7fd821dca0b2088bde7e0a2a06bfe59e1ba5c6.zip |
Asynchronous ActionMailer
Any ActionMailer class can be set to render and delier messages using
the new Rails Queue.
Some of this work was borrowed (with permission) from Nick Plante's
(zapnap) reqsue_mailer gem.
Diffstat (limited to 'actionmailer')
-rw-r--r-- | actionmailer/lib/action_mailer/async.rb | 41 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/base.rb | 7 | ||||
-rw-r--r-- | actionmailer/test/base_test.rb | 14 | ||||
-rw-r--r-- | actionmailer/test/fixtures/async_mailer/welcome.erb | 1 | ||||
-rw-r--r-- | actionmailer/test/mailers/async_mailer.rb | 3 |
5 files changed, 66 insertions, 0 deletions
diff --git a/actionmailer/lib/action_mailer/async.rb b/actionmailer/lib/action_mailer/async.rb new file mode 100644 index 0000000000..6f768ac286 --- /dev/null +++ b/actionmailer/lib/action_mailer/async.rb @@ -0,0 +1,41 @@ +module ActionMailer::Async + def self.included(base) + base.extend(ClassMethods) + end + + module ClassMethods + def method_missing(method_name, *args) + if action_methods.include?(method_name.to_s) + QueuedMessage.new(self, method_name, *args) + else + super + end + end + end + + class QueuedMessage + delegate :to_s, :to => :actual_message + + def initialize(mailer_class, method_name, *args) + @mailer_class = mailer_class + @method_name = method_name + *@args = *args + end + + def run + actual_message.deliver + end + + def deliver + Rails.queue << self + end + + def actual_message + @actual_message ||= @mailer_class.send(:new, @method_name, *@args).message + end + + def method_missing(method_name, *args) + actual_message.send(method_name, *args) + end + end +end diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 739f9a52a9..f40b85549e 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -456,6 +456,13 @@ module ActionMailer #:nodoc: super || action_methods.include?(method.to_s) end + def async=(truth) + if truth + require 'action_mailer/async' + include ActionMailer::Async + end + end + protected def set_payload_for_mail(payload, mail) #:nodoc: diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 1b2e39b3f7..fdc784029b 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -7,6 +7,9 @@ require 'active_support/time' require 'mailers/base_mailer' require 'mailers/proc_mailer' require 'mailers/asset_mailer' +require 'mailers/async_mailer' + +require 'rails/queueing' class BaseTest < ActiveSupport::TestCase def teardown @@ -419,6 +422,16 @@ class BaseTest < ActiveSupport::TestCase assert_equal(1, BaseMailer.deliveries.length) end + test "delivering message asynchronously" do + Rails.stubs(:queue).returns(Rails::Queueing::TestQueue.new) + AsyncMailer.delivery_method = :test + AsyncMailer.deliveries.clear + AsyncMailer.welcome.deliver + assert_equal(0, AsyncMailer.deliveries.length) + Rails.queue.drain + assert_equal(1, AsyncMailer.deliveries.length) + end + test "calling deliver, ActionMailer should yield back to mail to let it call :do_delivery on itself" do mail = Mail::Message.new mail.expects(:do_delivery).once @@ -434,6 +447,7 @@ class BaseTest < ActiveSupport::TestCase end test "should raise if missing template in implicit render" do + BaseMailer.deliveries.clear assert_raises ActionView::MissingTemplate do BaseMailer.implicit_different_template('missing_template').deliver end diff --git a/actionmailer/test/fixtures/async_mailer/welcome.erb b/actionmailer/test/fixtures/async_mailer/welcome.erb new file mode 100644 index 0000000000..01f3f00c63 --- /dev/null +++ b/actionmailer/test/fixtures/async_mailer/welcome.erb @@ -0,0 +1 @@ +Welcome
\ No newline at end of file diff --git a/actionmailer/test/mailers/async_mailer.rb b/actionmailer/test/mailers/async_mailer.rb new file mode 100644 index 0000000000..ce601e7343 --- /dev/null +++ b/actionmailer/test/mailers/async_mailer.rb @@ -0,0 +1,3 @@ +class AsyncMailer < BaseMailer + self.async = true +end |