devise-async 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,11 @@
1
1
  ## Unreleased
2
2
 
3
+ ## 0.5.0
4
+
5
+ * Added support for QueueClassic (jperville)
6
+ * Remove deprecated `DeviseAsync::Proxy` and `DeviseAsync.backend=`
7
+ * Improved comments throughout code
8
+
3
9
  ## 0.4.0
4
10
 
5
11
  * Enhancements
data/README.md CHANGED
@@ -7,6 +7,7 @@ Supported backends:
7
7
  * Resque
8
8
  * Sidekiq
9
9
  * Delayed::Job
10
+ * QueueClassic
10
11
 
11
12
  ## Installation
12
13
 
@@ -37,7 +38,7 @@ end
37
38
  Set your queuing backend by creating `config/initializers/devise_async.rb`:
38
39
 
39
40
  ```ruby
40
- # Supported options: :resque, :sidekiq, :delayed_job
41
+ # Supported options: :resque, :sidekiq, :delayed_job, :queue_classic
41
42
  Devise::Async.backend = :resque
42
43
  ```
43
44
 
@@ -52,9 +53,12 @@ Set `Devise::Async::Proxy` as Devise's mailer in `config/initializers/devise.rb`
52
53
  config.mailer = "Devise::Async::Proxy"
53
54
  ```
54
55
 
55
- Note: before devise 2.1.1 devise-async had issues with background jobs trying to run
56
+ WARNING 1: before devise 2.1.1 devise-async had issues with background jobs trying to run
56
57
  before the record was committed to the DB if the creation was transactioned.
57
58
 
59
+ WARNING 2: I intend to deprecate support for devise < 2.1.1 before 1.0.0 and drop support
60
+ in the 1.0.0 release. Please consider upgrading your Devise version.
61
+
58
62
  ## Advanced Options
59
63
 
60
64
  ### Custom mailer class
@@ -69,8 +73,8 @@ Devise::Async.mailer = "MyCustomMailer"
69
73
 
70
74
  ### Custom queue
71
75
 
72
- Let you specify a custom queue where to enqueue your background Devise jobs. Works
73
- only for Resque and Sidekiq. Defaults to :mailer.
76
+ Let you specify a custom queue where to enqueue your background Devise jobs.
77
+ Defaults to :mailer.
74
78
 
75
79
  ```ruby
76
80
  # config/initializers/devise_async.rb
@@ -91,6 +95,14 @@ Devise::Async.setup do |config|
91
95
  end
92
96
  ```
93
97
 
98
+ ## Testing
99
+
100
+ Be aware that since version 0.3.0 devise-async enqueues the background job in active
101
+ record's `after_commit` hook. If you're using rspec's `use_transactional_fixtures` the jobs
102
+ might not be enqueued as you'd expect.
103
+
104
+ More details in this stackoverflow [thread](http://stackoverflow.com/questions/13406248/how-do-i-get-devise-async-working-with-cucumber/13465089#13465089).
105
+
94
106
  ## Contributing
95
107
 
96
108
  1. Fork it
@@ -4,8 +4,8 @@ require File.expand_path('../lib/devise/async/version', __FILE__)
4
4
  Gem::Specification.new do |gem|
5
5
  gem.authors = ["Marcelo Silveira"]
6
6
  gem.email = ["marcelo@mhfs.com.br"]
7
- gem.description = %q{Send Devise's emails in background. Supports Resque, Sidekiq and Delayed::Job.}
8
- gem.summary = %q{Devise Async provides an easy way to configure Devise to send its emails asynchronously using your preferred queuing backend. It supports Resque, Sidekiq and Delayed::Job.}
7
+ gem.description = %q{Send Devise's emails in background. Supports Resque, Sidekiq, Delayed::Job and QueueClassic.}
8
+ gem.summary = %q{Devise Async provides an easy way to configure Devise to send its emails asynchronously using your preferred queuing backend. It supports Resque, Sidekiq, Delayed::Job and QueueClassic.}
9
9
  gem.homepage = "https://github.com/mhfs/devise-async/"
10
10
 
11
11
  gem.files = `git ls-files`.split($\)
@@ -24,6 +24,7 @@ Gem::Specification.new do |gem|
24
24
  gem.add_development_dependency "resque", "~> 1.20"
25
25
  gem.add_development_dependency "sidekiq", "~> 1.2"
26
26
  gem.add_development_dependency "delayed_job_active_record", "~> 0.3"
27
+ gem.add_development_dependency "queue_classic", "~> 2.0"
27
28
  gem.add_development_dependency "mocha", "~> 0.11"
28
29
  gem.add_development_dependency "minitest", "~> 3.0"
29
30
  end
@@ -9,10 +9,11 @@ module Devise
9
9
  autoload :Model, "devise/async/model"
10
10
 
11
11
  module Backend
12
- autoload :Base, "devise/async/backend/base"
13
- autoload :Resque, "devise/async/backend/resque"
14
- autoload :Sidekiq, "devise/async/backend/sidekiq"
15
- autoload :DelayedJob, "devise/async/backend/delayed_job"
12
+ autoload :Base, "devise/async/backend/base"
13
+ autoload :Resque, "devise/async/backend/resque"
14
+ autoload :Sidekiq, "devise/async/backend/sidekiq"
15
+ autoload :DelayedJob, "devise/async/backend/delayed_job"
16
+ autoload :QueueClassic, "devise/async/backend/queue_classic"
16
17
  end
17
18
 
18
19
  # Defines the queue backend to be used. Resque by default.
@@ -33,7 +34,8 @@ module Devise
33
34
  #
34
35
  # Devise::Async.setup do |config|
35
36
  # config.backend = :resque
36
- # config.mailer = "MyMailer"
37
+ # config.mailer = "MyMailer"
38
+ # config.queue = :my_custom_queue
37
39
  # end
38
40
  def self.setup
39
41
  yield self
@@ -41,20 +43,5 @@ module Devise
41
43
  end
42
44
  end
43
45
 
44
- # Just to be compatible with first release
45
- # TODO remove when appropriate
46
- module DeviseAsync
47
- class Proxy < Devise::Async::Proxy
48
- def initialize(method, resource)
49
- puts "DEPRECATION WARNING: DeviseAsync::Proxy has been deprecated. Please use Devise::Async::Proxy."
50
- super
51
- end
52
- end
53
-
54
- def self.backend=(value)
55
- puts "DEPRECATION WARNING: `DeviseAsync.backend=` has been deprecated. Please use `Devise::Async.backend=`."
56
- Devise::Async.backend = value
57
- end
58
- end
59
-
46
+ # Register devise-async model in Devise
60
47
  Devise.add_module(:async, :model => 'devise/async/model')
@@ -1,6 +1,8 @@
1
1
  module Devise
2
2
  module Async
3
3
  module Backend
4
+ # Gives the desired backend driver class to be used to enqueue
5
+ # jobs.
4
6
  def self.for(backend)
5
7
  const_get(backend.to_s.camelize)
6
8
  rescue NameError
@@ -0,0 +1,20 @@
1
+ require "queue_classic"
2
+
3
+ module Devise
4
+ module Async
5
+ module Backend
6
+ class QueueClassic < Base
7
+ def self.enqueue(method, *args)
8
+ queue = ::QC::Queue.new(Devise::Async.queue)
9
+ method = String(method) # QC won't serialize Symbol such as #{method}
10
+ args.unshift("#{self}.perform", method)
11
+ queue.enqueue(*args)
12
+ end
13
+
14
+ def self.perform(method, resource_class, resource_id)
15
+ new.perform(method, resource_class, resource_id)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -15,6 +15,13 @@ module Devise
15
15
  extend ActiveSupport::Concern
16
16
 
17
17
  included do
18
+ # Register hook to send all devise pending notifications.
19
+ #
20
+ # When supported by the ORM/database we send just after commit to
21
+ # prevent the backend of trying to fetch the record and send the
22
+ # notification before the record is committed to the databse.
23
+ #
24
+ # Otherwise we use after_save.
18
25
  if respond_to?(:after_commit) # AR only
19
26
  after_commit :send_devise_pending_notifications
20
27
  else # mongoid
@@ -24,14 +31,23 @@ module Devise
24
31
 
25
32
  protected
26
33
 
34
+ # This method overwrites devise's own `send_devise_notification`
35
+ # to capture all email notifications and enqueue it for background
36
+ # processing instead of sending it inline as devise does by
37
+ # default.
27
38
  def send_devise_notification(notification)
39
+ # If the record is dirty we keep pending notifications to be enqueued
40
+ # by the callback and avoid before commit job processing.
28
41
  if changed?
29
42
  devise_pending_notifications << notification
43
+ # If the record isn't dirty (aka has already been saved) enqueue right away
44
+ # because the callback has already been triggered.
30
45
  else
31
46
  Devise::Async::Worker.enqueue(notification, self.class.name, self.id.to_s)
32
47
  end
33
48
  end
34
49
 
50
+ # Send all pending notifications.
35
51
  def send_devise_pending_notifications
36
52
  devise_pending_notifications.each do |notification|
37
53
  # Use `id.to_s` to avoid problems with mongoid 2.4.X ids being serialized
@@ -1,7 +1,7 @@
1
1
  module Devise
2
2
  module Async
3
3
  class Proxy
4
- # catches all devise emails
4
+ # Catches all devise emails
5
5
  def self.method_missing(method, *args, &block)
6
6
  new(method, args.first)
7
7
  end
@@ -1,5 +1,5 @@
1
1
  module Devise
2
2
  module Async
3
- VERSION = "0.4.0"
3
+ VERSION = "0.5.0"
4
4
  end
5
5
  end
@@ -1,6 +1,8 @@
1
1
  module Devise
2
2
  module Async
3
3
  class Worker
4
+ # Used is the internal interface for devise-async to enqueue notifications
5
+ # to the desired backend.
4
6
  def self.enqueue(method, resource_class, resource_id)
5
7
  backend_class.enqueue(method, resource_class, resource_id)
6
8
  end
@@ -0,0 +1,29 @@
1
+ require "test_helper"
2
+
3
+ module Devise
4
+ module Async
5
+ module Backend
6
+ describe "QueueClassic" do
7
+ it "enqueues job" do
8
+ ::QC::Queue.any_instance.expects(:enqueue).with(
9
+ "Devise::Async::Backend::QueueClassic.perform",
10
+ "mailer_method", "User", 123)
11
+ QueueClassic.enqueue(:mailer_method, "User", 123)
12
+ end
13
+
14
+ it "delegates to devise mailer when delivering" do
15
+ user = create_user
16
+ ActionMailer::Base.deliveries = []
17
+ Backend::QueueClassic.perform(:confirmation_instructions, "User", user.id)
18
+ ActionMailer::Base.deliveries.size.must_equal 1
19
+ end
20
+
21
+ it "enqueues to configured queue" do
22
+ queue = mock(:enqueue => nil)
23
+ ::QC::Queue.expects(:new).with(:custom_queue).once.returns(queue)
24
+ QueueClassic.enqueue(:mailer_method, "User", 123)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -15,6 +15,10 @@ module Devise
15
15
  Backend.for(:delayed_job).must_equal Backend::DelayedJob
16
16
  end
17
17
 
18
+ it "gives queue classic as the backend" do
19
+ Backend.for(:queue_classic).must_equal Backend::QueueClassic
20
+ end
21
+
18
22
  it "alerts about unsupported backend" do
19
23
  assert_raises ArgumentError do
20
24
  Backend.for(:unsupported_backend)
@@ -23,6 +23,13 @@ module Devise
23
23
  Backend::DelayedJob.expects(:enqueue).with(:mailer_method, "User", 123)
24
24
  Worker.enqueue(:mailer_method, "User", 123)
25
25
  end
26
+
27
+ it "enqueues job using the queue classic backend" do
28
+ Devise::Async.backend = :queue_classic
29
+
30
+ Backend::QueueClassic.expects(:enqueue).with(:mailer_method, "User", 123)
31
+ Worker.enqueue(:mailer_method, "User", 123)
32
+ end
26
33
  end
27
34
  end
28
35
  end
@@ -7,6 +7,7 @@ Devise.setup do |config|
7
7
  config.mailer_sender = "please-change-me-at-config-initializers-devise@example.com"
8
8
 
9
9
  # Configure the class responsible to send e-mails.
10
+ # config.mailer = "Devise::Mailer"
10
11
  config.mailer = "Devise::Async::Proxy"
11
12
 
12
13
  # ==> ORM configuration
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise-async
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-04 00:00:00.000000000 Z
12
+ date: 2012-11-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: devise
@@ -139,6 +139,22 @@ dependencies:
139
139
  - - ~>
140
140
  - !ruby/object:Gem::Version
141
141
  version: '0.3'
142
+ - !ruby/object:Gem::Dependency
143
+ name: queue_classic
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ~>
148
+ - !ruby/object:Gem::Version
149
+ version: '2.0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: '2.0'
142
158
  - !ruby/object:Gem::Dependency
143
159
  name: mocha
144
160
  requirement: !ruby/object:Gem::Requirement
@@ -171,7 +187,8 @@ dependencies:
171
187
  - - ~>
172
188
  - !ruby/object:Gem::Version
173
189
  version: '3.0'
174
- description: Send Devise's emails in background. Supports Resque, Sidekiq and Delayed::Job.
190
+ description: Send Devise's emails in background. Supports Resque, Sidekiq, Delayed::Job
191
+ and QueueClassic.
175
192
  email:
176
193
  - marcelo@mhfs.com.br
177
194
  executables: []
@@ -191,6 +208,7 @@ files:
191
208
  - lib/devise/async/backend.rb
192
209
  - lib/devise/async/backend/base.rb
193
210
  - lib/devise/async/backend/delayed_job.rb
211
+ - lib/devise/async/backend/queue_classic.rb
194
212
  - lib/devise/async/backend/resque.rb
195
213
  - lib/devise/async/backend/sidekiq.rb
196
214
  - lib/devise/async/model.rb
@@ -199,6 +217,7 @@ files:
199
217
  - lib/devise/async/worker.rb
200
218
  - test/devise/async/backend/base_test.rb
201
219
  - test/devise/async/backend/delayed_job_test.rb
220
+ - test/devise/async/backend/queue_classic_test.rb
202
221
  - test/devise/async/backend/resque_test.rb
203
222
  - test/devise/async/backend/sidekiq_test.rb
204
223
  - test/devise/async/backend_test.rb
@@ -232,7 +251,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
232
251
  version: '0'
233
252
  segments:
234
253
  - 0
235
- hash: -1947628383257764484
254
+ hash: -1534184390293388048
236
255
  required_rubygems_version: !ruby/object:Gem::Requirement
237
256
  none: false
238
257
  requirements:
@@ -241,18 +260,19 @@ required_rubygems_version: !ruby/object:Gem::Requirement
241
260
  version: '0'
242
261
  segments:
243
262
  - 0
244
- hash: -1947628383257764484
263
+ hash: -1534184390293388048
245
264
  requirements: []
246
265
  rubyforge_project:
247
266
  rubygems_version: 1.8.23
248
267
  signing_key:
249
268
  specification_version: 3
250
269
  summary: Devise Async provides an easy way to configure Devise to send its emails
251
- asynchronously using your preferred queuing backend. It supports Resque, Sidekiq
252
- and Delayed::Job.
270
+ asynchronously using your preferred queuing backend. It supports Resque, Sidekiq,
271
+ Delayed::Job and QueueClassic.
253
272
  test_files:
254
273
  - test/devise/async/backend/base_test.rb
255
274
  - test/devise/async/backend/delayed_job_test.rb
275
+ - test/devise/async/backend/queue_classic_test.rb
256
276
  - test/devise/async/backend/resque_test.rb
257
277
  - test/devise/async/backend/sidekiq_test.rb
258
278
  - test/devise/async/backend_test.rb