Skip to content

Commit

Permalink
Fix merge conflicts.
Browse files Browse the repository at this point in the history
  • Loading branch information
barelyknown committed Apr 29, 2015
2 parents 6db0f47 + b7ca260 commit e6079a6
Show file tree
Hide file tree
Showing 12 changed files with 152 additions and 16 deletions.
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Devise Async [![Build Status](https://secure.travis-ci.org/mhfs/devise-async.png)](http://travis-ci.org/mhfs/devise-async)
# Devise Async

[![Tag](https://img.shields.io/github/tag/mhfs/devise-async.svg?style=flat-square)](https://github.com/mhfs/devise-async/releases) [![Build Status](https://img.shields.io/travis/mhfs/devise-async.svg?style=flat-square)](https://travis-ci.org/mhfs/devise-async) [![Code Climate](https://img.shields.io/codeclimate/github/mhfs/devise-async.svg?style=flat-square)](https://codeclimate.com/github/mhfs/devise-async)

Devise Async provides an easy way to configure Devise to send its emails asynchronously using your preferred queuing backend.

Expand All @@ -11,6 +13,7 @@ Supported backends:
* Torquebox
* Backburner
* Que
* SuckerPunch

## Installation

Expand Down Expand Up @@ -41,7 +44,7 @@ end
Set your queuing backend by creating `config/initializers/devise_async.rb`:

```ruby
# Supported options: :resque, :sidekiq, :delayed_job, :queue_classic, :torquebox, :backburner, :que
# Supported options: :resque, :sidekiq, :delayed_job, :queue_classic, :torquebox, :backburner, :que, :sucker_punch
Devise::Async.backend = :resque
```

Expand Down Expand Up @@ -75,6 +78,16 @@ Defaults to :mailer.
Devise::Async.queue = :my_custom_queue
```

### Custom priority

You can specify a custom priority for created background jobs in Devise or Backburner.
If no value is specified, jobs will be enqueued with whatever default priority is configured in Devise or Backburner.

```ruby
# config/initializers/devise_async.rb
Devise::Async.priority = 10
```

### Setup via block

To avoid repeating `Devise::Async` in the initializer file you can use the block syntax
Expand Down
4 changes: 4 additions & 0 deletions lib/devise/async.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ module Backend
mattr_accessor :queue
@@queue = :mailer

# Defines the priority in which the background job will be enqueued. Defaults to the default of the backend you are using.
mattr_accessor :priority
@@priority = nil

# Defines the enabled configuration that if set to false the emails will be sent synchronously
mattr_accessor :enabled
@@enabled = true
Expand Down
4 changes: 4 additions & 0 deletions lib/devise/async/backend/backburner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ def self.perform(*args)
def self.queue
Devise::Async.queue
end

def self.queue_priority
Devise::Async.priority.nil? ? ::Backburner.configuration.default_priority : Devise::Async.priority
end
end
end
end
Expand Down
20 changes: 15 additions & 5 deletions lib/devise/async/backend/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,27 @@ def self.enqueue(*args)
#
# It uses `orm_adapter` API to fetch the record in order to enforce
# compatibility among diferent ORMs.
#
# This method is executed within the scope of the locale of
# the calling thread.
def perform(method, resource_class, resource_id, *args)
resource = resource_class.constantize.to_adapter.get!(resource_id)
args[-1] = args.last.symbolize_keys if args.last.is_a?(Hash)
mailer = mailer_class(resource).send(method, resource, *args)
mailer.send(deliver_method(mailer))
I18n.with_locale locale_from_args(args) do
resource = resource_class.constantize.to_adapter.get!(resource_id)
args[-1] = args.last.symbolize_keys if args.last.is_a?(Hash)
mailer = mailer_class(resource).send(method, resource, *args)
mailer.send(deliver_method(mailer))
end
end

private

def mailer_class(resource = nil)
@mailer_class ||= resource.try(:devise_mailer) || Devise.mailer
@mailer_class ||= resource.send(:devise_mailer) || Devise.mailer
end

def locale_from_args(args)
args_last = args.last
args_last.delete('locale') if args_last.is_a?(Hash)
end

# Use #deliver_now if supported, otherwise falls back to #deliver.
Expand Down
6 changes: 5 additions & 1 deletion lib/devise/async/backend/delayed_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ module Async
module Backend
class DelayedJob < Base
def self.enqueue(*args)
new.delay(:queue => Devise::Async.queue).perform(*args)
new.delay(:queue => Devise::Async.queue, :priority => priority).perform(*args)
end

def self.priority
Devise::Async.priority.nil? ? Delayed::Worker.default_priority : Devise::Async.priority
end
end
end
Expand Down
23 changes: 23 additions & 0 deletions lib/devise/async/model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ module Async
def send_devise_notification(notification, *args)
return super unless Devise::Async.enabled

# The current locale has to be remembered until the actual sending
# of an email because it is scoped to the current thread. Hence,
# using asynchronous mechanisms that use another thread to send an
# email the currently used locale will be gone later.
args = args_with_current_locale(args)

# If the record is dirty we keep pending notifications to be enqueued
# by the callback and avoid before commit job processing.
if changed?
Expand All @@ -51,6 +57,23 @@ def send_devise_pending_notifications
def devise_pending_notifications
@devise_pending_notifications ||= []
end

private

def args_with_current_locale(args)
# The default_locale is taken in any case. Hence, the args do not have
# to be adapted if default_locale and current locale are equal.
args = add_current_locale_to_args(args) if I18n.locale != I18n.default_locale
args
end

def add_current_locale_to_args(args)
# Devise expects a hash as the last parameter for Mailer methods.
opts = args.last.is_a?(Hash) ? args.pop : {}
opts['locale'] = I18n.locale
args.push(opts)
end

end
end
end
12 changes: 12 additions & 0 deletions test/devise/async/backend/backburner_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ module Backend
Backend::Backburner.perform(:confirmation_instructions, "User", user.id, {})
ActionMailer::Base.deliveries.size.must_equal 1
end

describe ".queue_priority" do
it "returns the right priority when set" do
Devise::Async.priority = 15
Backburner.queue_priority.must_equal 15
Devise::Async.priority = nil
end

it "returns default priority when no priority is set" do
Backburner.queue_priority.must_equal ::Backburner.configuration.default_priority
end
end
end
end
end
Expand Down
28 changes: 23 additions & 5 deletions test/devise/async/backend/base_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,33 @@
module Devise
module Async
module Backend

describe "Base" do

it "delegates to configured mailer" do
before do
Devise.mailer = "MyMailer"
user = create_user
mailer_instance = mock(:deliver => true)
@user = create_user
end

MyMailer.expects(:confirmation_instructions).once.returns(mailer_instance)
Base.new.perform(:confirmation_instructions, "User", user.id, {})
after do
Devise.mailer = "Devise::Mailer"
end

it "delegates to configured mailer" do
@mailer_instance = mock(:deliver => true)

MyMailer.expects(:confirmation_instructions).once.returns(@mailer_instance)
Base.new.perform(:confirmation_instructions, "User", @user.id, {})
end

it "executes within the locale scope if a locale is given via args" do
I18n.expects(:with_locale).once.with(:de)
Base.new.perform(:confirmation_instructions, "User", @user.id, { 'locale' => :de })
end

it "does not execute within the locale scope if no locale is given via args" do
I18n.expects(:"locale=").never
Base.new.perform(:confirmation_instructions, "User", @user.id, {})
end

it "delegates to model configured mailer" do
Expand Down
14 changes: 13 additions & 1 deletion test/devise/async/backend/delayed_job_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module Backend
it "enqueues job" do
delayed_instance = mock()
delayed_instance.expects(:perform).once.with(:mailer_method, "User", 123, {})
DelayedJob.any_instance.expects(:delay).once.returns(delayed_instance)
DelayedJob.any_instance.expects(:delay).with(:queue => Devise::Async.queue, :priority => DelayedJob.priority).once.returns(delayed_instance)

DelayedJob.enqueue(:mailer_method, "User", 123, {})
end
Expand All @@ -18,6 +18,18 @@ module Backend
Backend::DelayedJob.new.perform(:confirmation_instructions, "User", user.id, {})
ActionMailer::Base.deliveries.size.must_equal 1
end

describe ".priority" do
it "returns it when the priority is set" do
Devise::Async.priority = 15
DelayedJob.priority.must_equal 15
Devise::Async.priority = nil
end

it "returns the default DJ priority when the priority is not set it" do
DelayedJob.priority.must_equal Delayed::Worker.default_priority
end
end
end
end
end
Expand Down
24 changes: 24 additions & 0 deletions test/devise/async/model_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,30 @@ module Async
admin.send(:devise_pending_notifications).must_equal []
Worker.expects(:enqueue).never
end

describe "custom locale set" do

# Set a custom locale
before { I18n.locale = :de }

# locale == nil indicates the usage of the default_locale
after { I18n.locale = nil }

it "should set the current locale to the args" do
admin = create_admin
Worker.expects(:enqueue).with(:confirmation_instructions, "Admin", admin.id.to_s, instance_of(String), { 'locale' => :de })
admin.send_confirmation_instructions
end
end

describe "default locale set" do

it "should not set the current locale to the args" do
admin = create_admin
Worker.expects(:enqueue).with(:confirmation_instructions, "Admin", admin.id.to_s, instance_of(String), {})
admin.send_confirmation_instructions
end
end
end
end
end
12 changes: 10 additions & 2 deletions test/devise/async_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

module Devise
describe "Async" do

after do
Async.backend = :resque
end

it "yields self when setup is called" do
Async.setup { |config| config.must_equal Async }
end
Expand All @@ -16,8 +21,11 @@ module Devise
Async.backend.must_equal false
end

after do
Async.backend = :resque
it "stores priority config" do
Async.priority = 15
Async.priority.must_equal 15
Async.priority = nil
end

end
end
4 changes: 4 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
require "minitest/mock"
require "mocha/setup"

require "action_controller"

require "devise"
require "devise/async"
require "rails/all"
Expand All @@ -25,3 +27,5 @@
include TestHelpers

load File.dirname(__FILE__) + "/support/rails_app/db/schema.rb"

I18n.enforce_available_locales = false

0 comments on commit e6079a6

Please sign in to comment.