aboutsummaryrefslogtreecommitdiffstats
path: root/actionmailer
diff options
context:
space:
mode:
authorBrian Cardarella <bcardarella@gmail.com>2012-06-23 14:36:09 -0400
committerBrian Cardarella <bcardarella@gmail.com>2012-06-23 14:36:09 -0400
commitdc7fd821dca0b2088bde7e0a2a06bfe59e1ba5c6 (patch)
treebf317b8bc64a1842aa3c5e65b3f829e1f2eaa9f1 /actionmailer
parent3726080ecea8b34edeac37f358e8dd050cbb00cb (diff)
downloadrails-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.rb41
-rw-r--r--actionmailer/lib/action_mailer/base.rb7
-rw-r--r--actionmailer/test/base_test.rb14
-rw-r--r--actionmailer/test/fixtures/async_mailer/welcome.erb1
-rw-r--r--actionmailer/test/mailers/async_mailer.rb3
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