aboutsummaryrefslogtreecommitdiffstats
path: root/actionmailer/lib/action_mailer
diff options
context:
space:
mode:
Diffstat (limited to 'actionmailer/lib/action_mailer')
-rw-r--r--actionmailer/lib/action_mailer/async.rb41
-rw-r--r--actionmailer/lib/action_mailer/base.rb141
-rw-r--r--actionmailer/lib/action_mailer/queued_message.rb37
-rw-r--r--actionmailer/lib/action_mailer/railtie.rb2
4 files changed, 100 insertions, 121 deletions
diff --git a/actionmailer/lib/action_mailer/async.rb b/actionmailer/lib/action_mailer/async.rb
deleted file mode 100644
index a364342745..0000000000
--- a/actionmailer/lib/action_mailer/async.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-require 'delegate'
-
-module ActionMailer
- module Async
- def method_missing(method_name, *args)
- if action_methods.include?(method_name.to_s)
- QueuedMessage.new(queue, self, method_name, *args)
- else
- super
- end
- end
-
- def queue
- Rails.queue
- end
-
- class QueuedMessage < ::Delegator
- attr_reader :queue
-
- def initialize(queue, mailer_class, method_name, *args)
- @queue = queue
- @mailer_class = mailer_class
- @method_name = method_name
- @args = args
- end
-
- def __getobj__
- @actual_message ||= @mailer_class.send(:new, @method_name, *@args).message
- end
-
- def run
- __getobj__.deliver
- end
-
- # Will push the message onto the Queue to be processed
- def deliver
- @queue << self
- end
- end
- end
-end \ No newline at end of file
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb
index 3cb98df6d5..01a1873636 100644
--- a/actionmailer/lib/action_mailer/base.rb
+++ b/actionmailer/lib/action_mailer/base.rb
@@ -1,8 +1,10 @@
require 'mail'
+require 'action_mailer/queued_message'
require 'action_mailer/collector'
require 'active_support/core_ext/string/inflections'
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/module/anonymous'
+require 'active_support/queueing'
require 'action_mailer/log_subscriber'
module ActionMailer
@@ -349,69 +351,55 @@ module ActionMailer
# These options are specified on the class level, like
# <tt>ActionMailer::Base.raise_delivery_errors = true</tt>
#
- # * <tt>default</tt> - You can pass this in at a class level as well as within
- # the class itself as per the above section.
- #
- # * <tt>logger</tt> - the logger is used for generating information on the
- # mailing run if available. Can be set to +nil+ for no logging. Compatible
- # with both Ruby's own Logger and Log4r loggers.
- #
- # * <tt>smtp_settings</tt> - Allows detailed configuration for <tt>:smtp</tt>
- # delivery method:
- # * <tt>:address</tt> - Allows you to use a remote mail server. Just change
- # it from its default "localhost" setting.
- # * <tt>:port</tt> - On the off chance that your mail server doesn't run on
- # port 25, you can change it.
- # * <tt>:domain</tt> - If you need to specify a HELO domain, you can do it
- # here.
- # * <tt>:user_name</tt> - If your mail server requires authentication, set
- # the username in this setting.
- # * <tt>:password</tt> - If your mail server requires authentication, set
- # the password in this setting.
- # * <tt>:authentication</tt> - If your mail server requires authentication,
- # you need to specify the authentication type here. This is a symbol and
- # one of <tt>:plain</tt> (will send the password in the clear), <tt>:login</tt>
- # (will send password Base64 encoded) or <tt>:cram_md5</tt> (combines a
- # Challenge/Response mechanism to exchange information and a cryptographic
- # Message Digest 5 algorithm to hash important information).
- # * <tt>:enable_starttls_auto</tt> - When set to +true+, detects if STARTTLS
- # is enabled in your SMTP server and starts to use it.
- # * <tt>:openssl_verify_mode</tt> - When using TLS, you can set how OpenSSL
- # checks the certificate. This is really useful if you need to validate a
- # self-signed and/or a wildcard certificate. You can use the name of an
- # OpenSSL verify constant ('none', 'peer', 'client_once', 'fail_if_no_peer_cert')
- # or directly the constant (OpenSSL::SSL::VERIFY_NONE, OpenSSL::SSL::VERIFY_PEER,...).
- #
- # * <tt>sendmail_settings</tt> - Allows you to override options for the
- # <tt>:sendmail</tt> delivery method.
- # * <tt>:location</tt> - The location of the sendmail executable. Defaults
- # to <tt>/usr/sbin/sendmail</tt>.
- # * <tt>:arguments</tt> - The command line arguments. Defaults to <tt>-i -t</tt>
- # with <tt>-f sender@address</tt> added automatically before the message
- # is sent.
- #
- # * <tt>file_settings</tt> - Allows you to override options for the <tt>:file</tt>
- # delivery method.
- # * <tt>:location</tt> - The directory into which emails will be written.
- # Defaults to the application <tt>tmp/mails</tt>.
- #
- # * <tt>raise_delivery_errors</tt> - Whether or not errors should be raised if
- # the email fails to be delivered.
- #
- # * <tt>delivery_method</tt> - Defines a delivery method. Possible values are
- # <tt>:smtp</tt> (default), <tt>:sendmail</tt>, <tt>:test</tt>, and <tt>:file</tt>.
- # Or you may provide a custom delivery method object e.g. MyOwnDeliveryMethodClass.
- # See the Mail gem documentation on the interface you need to implement for
- # a custom delivery agent.
- #
- # * <tt>perform_deliveries</tt> - Determines whether emails are actually sent
- # from Action Mailer when you call <tt>.deliver</tt> on an mail message or
- #  on an Action Mailer method. This is on by default but can be turned off to
- # aid in functional testing.
- #
- # * <tt>deliveries</tt> - Keeps an array of all the emails sent out through
- # the Action Mailer with <tt>delivery_method :test</tt>. Most useful for
- # unit and functional testing.
+ # * <tt>default</tt> - You can pass this in at a class level as well as within the class itself as
+ # per the above section.
+ #
+ # * <tt>logger</tt> - the logger is used for generating information on the mailing run if available.
+ # Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers.
+ #
+ # * <tt>smtp_settings</tt> - Allows detailed configuration for <tt>:smtp</tt> delivery method:
+ # * <tt>:address</tt> - Allows you to use a remote mail server. Just change it from its default
+ # "localhost" setting.
+ # * <tt>:port</tt> - On the off chance that your mail server doesn't run on port 25, you can change it.
+ # * <tt>:domain</tt> - If you need to specify a HELO domain, you can do it here.
+ # * <tt>:user_name</tt> - If your mail server requires authentication, set the username in this setting.
+ # * <tt>:password</tt> - If your mail server requires authentication, set the password in this setting.
+ # * <tt>:authentication</tt> - If your mail server requires authentication, you need to specify the
+ # authentication type here.
+ # This is a symbol and one of <tt>:plain</tt> (will send the password in the clear), <tt>:login</tt> (will
+ # send password Base64 encoded) or <tt>:cram_md5</tt> (combines a Challenge/Response mechanism to exchange
+ # information and a cryptographic Message Digest 5 algorithm to hash important information)
+ # * <tt>:enable_starttls_auto</tt> - When set to true, detects if STARTTLS is enabled in your SMTP server
+ # and starts to use it.
+ # * <tt>:openssl_verify_mode</tt> - When using TLS, you can set how OpenSSL checks the certificate. This is
+ # really useful if you need to validate a self-signed and/or a wildcard certificate. You can use the name
+ # of an OpenSSL verify constant ('none', 'peer', 'client_once','fail_if_no_peer_cert') or directly the
+ # constant (OpenSSL::SSL::VERIFY_NONE, OpenSSL::SSL::VERIFY_PEER,...).
+ #
+ # * <tt>sendmail_settings</tt> - Allows you to override options for the <tt>:sendmail</tt> delivery method.
+ # * <tt>:location</tt> - The location of the sendmail executable. Defaults to <tt>/usr/sbin/sendmail</tt>.
+ # * <tt>:arguments</tt> - The command line arguments. Defaults to <tt>-i -t</tt> with <tt>-f sender@address</tt>
+ # added automatically before the message is sent.
+ #
+ # * <tt>file_settings</tt> - Allows you to override options for the <tt>:file</tt> delivery method.
+ # * <tt>:location</tt> - The directory into which emails will be written. Defaults to the application
+ # <tt>tmp/mails</tt>.
+ #
+ # * <tt>raise_delivery_errors</tt> - Whether or not errors should be raised if the email fails to be delivered.
+ #
+ # * <tt>delivery_method</tt> - Defines a delivery method. Possible values are <tt>:smtp</tt> (default),
+ # <tt>:sendmail</tt>, <tt>:test</tt>, and <tt>:file</tt>. Or you may provide a custom delivery method
+ # object e.g. MyOwnDeliveryMethodClass. See the Mail gem documentation on the interface you need to
+ # implement for a custom delivery agent.
+ #
+ # * <tt>perform_deliveries</tt> - Determines whether emails are actually sent from Action Mailer when you
+ # call <tt>.deliver</tt> on an mail message or on an Action Mailer method. This is on by default but can
+ # be turned off to aid in functional testing.
+ #
+ # * <tt>deliveries</tt> - Keeps an array of all the emails sent out through the Action Mailer with
+ # <tt>delivery_method :test</tt>. Most useful for unit and functional testing.
+ #
+ # * <tt>queue</> - The queue that will be used to deliver the mail. The queue should expect a job that responds to <tt>run</tt>.
class Base < AbstractController::Base
include DeliveryMethods
abstract!
@@ -426,7 +414,7 @@ module ActionMailer
self.protected_instance_variables = [:@_action_has_layout]
- helper ActionMailer::MailHelper
+ helper ActionMailer::MailHelper
private_class_method :new # :nodoc:
@@ -438,6 +426,9 @@ module ActionMailer
:parts_order => [ "text/plain", "text/enriched", "text/html" ]
}.freeze
+ class_attribute :queue
+ self.queue = ActiveSupport::SynchronousQueue.new
+
class << self
# Register one or more Observers which will be notified when mail is delivered.
def register_observers(*observers)
@@ -516,19 +507,6 @@ module ActionMailer
super || action_methods.include?(method.to_s)
end
- # Will force ActionMailer to push new messages to the queue defined
- # in the ActionMailer class when set to true.
- #
- # class WelcomeMailer < ActionMailer::Base
- # self.async = true
- # end
- def async=(truth)
- if truth
- require 'action_mailer/async'
- extend ActionMailer::Async
- end
- end
-
protected
def set_payload_for_mail(payload, mail) # :nodoc:
@@ -543,9 +521,12 @@ module ActionMailer
payload[:mail] = mail.encoded
end
- def method_missing(method, *args) # :nodoc:
- return super unless respond_to?(method)
- new(method, *args).message
+ def method_missing(method_name, *args)
+ if action_methods.include?(method_name.to_s)
+ QueuedMessage.new(queue, self, method_name, *args)
+ else
+ super
+ end
end
end
diff --git a/actionmailer/lib/action_mailer/queued_message.rb b/actionmailer/lib/action_mailer/queued_message.rb
new file mode 100644
index 0000000000..8d200617c4
--- /dev/null
+++ b/actionmailer/lib/action_mailer/queued_message.rb
@@ -0,0 +1,37 @@
+require 'delegate'
+
+module ActionMailer
+ class QueuedMessage < ::Delegator
+ attr_reader :queue
+
+ def initialize(queue, mailer_class, method_name, *args)
+ @queue = queue
+ @job = DeliveryJob.new(mailer_class, method_name, args)
+ end
+
+ def __getobj__
+ @job.message
+ end
+
+ # Queues the message for delivery.
+ def deliver
+ tap { @queue.push @job }
+ end
+
+ class DeliveryJob
+ def initialize(mailer_class, method_name, args)
+ @mailer_class = mailer_class
+ @method_name = method_name
+ @args = args
+ end
+
+ def message
+ @message ||= @mailer_class.send(:new, @method_name, *@args).message
+ end
+
+ def run
+ message.deliver
+ end
+ end
+ end
+end
diff --git a/actionmailer/lib/action_mailer/railtie.rb b/actionmailer/lib/action_mailer/railtie.rb
index 5bd05c24b8..abf6ad80cf 100644
--- a/actionmailer/lib/action_mailer/railtie.rb
+++ b/actionmailer/lib/action_mailer/railtie.rb
@@ -19,6 +19,8 @@ module ActionMailer
options.javascripts_dir ||= paths["public/javascripts"].first
options.stylesheets_dir ||= paths["public/stylesheets"].first
+ options.queue ||= app.queue
+
# make sure readers methods get compiled
options.asset_path ||= app.config.asset_path
options.asset_host ||= app.config.asset_host