diff options
-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 |