Skip to content

Commit

Permalink
Support deferred Mailer deliver with deliver_later
Browse files Browse the repository at this point in the history
Re-opens [#4224][]

By default, all `Devise::Models::Authenticatable`-initiated Action
Mailer deliveries are transmitted immediately (within the
request-response cycle).

Transmitting emails and interacting with any third-party services over
SMTP or HTTP risk service outages and other types of network-related
failures.

This commit adds support for deferring delivery to be done from an
Action Job background worker queue through the [deliver_later][] method.

```ruby
 # config/initializers/devise.rb
Devise.mailer_delivery_method = :deliver_later
```

[#4224]: #4224
[deliver_now]: https://edgeapi.rubyonrails.org/classes/ActionMailer/MessageDelivery.html#method-i-deliver_now
[deliver_later]: https://edgeapi.rubyonrails.org/classes/ActionMailer/MessageDelivery.html#method-i-deliver_later
  • Loading branch information
seanpdoyle committed Jan 10, 2024
1 parent e2242a9 commit b585c19
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

* enhancements
* Removed deprecations warning output for `Devise::Models::Authenticatable::BLACKLIST_FOR_SERIALIZATION` (@soartec-lab)
* Added `Devise.mailer_delivery_method` configuration to enable deferring email delivery with `:deliver_later` [#5610](https://github.com/heartcombo/devise/pull/5610) [@seanpdoyle](https://github.com/seanpdoyle)

* bug fixes
* Respect locale set by controller in failure app. Devise will carry over the current I18n.locale option when triggering authentication, and will wrap the failure app call with it. [#5567](https://github.com/heartcombo/devise/pull/5567)
Expand Down
4 changes: 4 additions & 0 deletions lib/devise.rb
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ module Test
mattr_accessor :send_password_change_notification
@@send_password_change_notification = false

# Used to control when to deliver Action Mailer emails
mattr_accessor :mailer_delivery_method
@@mailer_delivery_method = :deliver_now

# Scoped views. Since it relies on fallbacks to render default views, it's
# turned off by default.
mattr_accessor :scoped_views
Expand Down
2 changes: 1 addition & 1 deletion lib/devise/models/authenticatable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ def devise_mailer
#
def send_devise_notification(notification, *args)
message = devise_mailer.send(notification, self, *args)
message.deliver_now
message.public_send(Devise.mailer_delivery_method)
end

def downcase_keys
Expand Down
3 changes: 3 additions & 0 deletions lib/generators/templates/devise.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
# Configure the class responsible to send e-mails.
# config.mailer = 'Devise::Mailer'

# Configure when to send e-mails.
# config.mailer_delivery_method = :deliver_now

# Configure the parent class responsible to send e-mails.
# config.parent_mailer = 'ActionMailer::Base'

Expand Down
16 changes: 16 additions & 0 deletions test/mailers/mailer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,20 @@ def computed_reply_to
assert mail.from, "from@example.com"
assert mail.reply_to, "reply_to@example.com"
end

test "defaults to immediate delivery" do
create_user

assert_not_empty ActionMailer::Base.deliveries
assert_empty ActiveJob::Base.queue_adapter.enqueued_jobs
end

test "supports deferred delivery with Devise.mailer_delivery_method = :deliver_later" do
swap Devise, mailer_delivery_method: :deliver_later do
create_user

assert_empty ActionMailer::Base.deliveries
assert_not_empty ActiveJob::Base.queue_adapter.enqueued_jobs
end
end
end

0 comments on commit b585c19

Please sign in to comment.