diff options
Diffstat (limited to 'actionmailer/lib/action_mailer')
-rw-r--r-- | actionmailer/lib/action_mailer/async.rb | 41 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/base.rb | 141 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/queued_message.rb | 37 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/railtie.rb | 2 |
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 |