activejob 5.0.7.2 → 5.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activejob might be problematic. Click here for more details.

Files changed (37) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +24 -221
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +1 -1
  5. data/lib/active_job.rb +5 -5
  6. data/lib/active_job/arguments.rb +7 -19
  7. data/lib/active_job/base.rb +11 -9
  8. data/lib/active_job/callbacks.rb +3 -3
  9. data/lib/active_job/configured_job.rb +1 -1
  10. data/lib/active_job/core.rb +14 -9
  11. data/lib/active_job/enqueuing.rb +7 -32
  12. data/lib/active_job/exceptions.rb +122 -0
  13. data/lib/active_job/execution.rb +5 -2
  14. data/lib/active_job/gem_version.rb +3 -3
  15. data/lib/active_job/logging.rb +56 -56
  16. data/lib/active_job/queue_adapter.rb +14 -26
  17. data/lib/active_job/queue_adapters.rb +2 -2
  18. data/lib/active_job/queue_adapters/async_adapter.rb +4 -4
  19. data/lib/active_job/queue_adapters/backburner_adapter.rb +1 -1
  20. data/lib/active_job/queue_adapters/delayed_job_adapter.rb +1 -1
  21. data/lib/active_job/queue_adapters/qu_adapter.rb +3 -3
  22. data/lib/active_job/queue_adapters/que_adapter.rb +1 -1
  23. data/lib/active_job/queue_adapters/queue_classic_adapter.rb +4 -4
  24. data/lib/active_job/queue_adapters/resque_adapter.rb +5 -5
  25. data/lib/active_job/queue_adapters/sidekiq_adapter.rb +11 -11
  26. data/lib/active_job/queue_adapters/sneakers_adapter.rb +3 -3
  27. data/lib/active_job/queue_adapters/sucker_punch_adapter.rb +3 -3
  28. data/lib/active_job/queue_adapters/test_adapter.rb +13 -17
  29. data/lib/active_job/queue_name.rb +2 -3
  30. data/lib/active_job/queue_priority.rb +1 -2
  31. data/lib/active_job/railtie.rb +4 -4
  32. data/lib/active_job/test_case.rb +1 -1
  33. data/lib/active_job/test_helper.rb +78 -39
  34. data/lib/active_job/version.rb +1 -1
  35. data/lib/rails/generators/job/job_generator.rb +12 -12
  36. data/lib/rails/generators/job/templates/application_job.rb +5 -0
  37. metadata +9 -7
@@ -1,4 +1,4 @@
1
- require 'backburner'
1
+ require "backburner"
2
2
 
3
3
  module ActiveJob
4
4
  module QueueAdapters
@@ -1,4 +1,4 @@
1
- require 'delayed_job'
1
+ require "delayed_job"
2
2
 
3
3
  module ActiveJob
4
4
  module QueueAdapters
@@ -1,4 +1,4 @@
1
- require 'qu'
1
+ require "qu"
2
2
 
3
3
  module ActiveJob
4
4
  module QueueAdapters
@@ -20,7 +20,7 @@ module ActiveJob
20
20
  qu_job = Qu::Payload.new(klass: JobWrapper, args: [job.serialize]).tap do |payload|
21
21
  payload.instance_variable_set(:@queue, job.queue_name)
22
22
  end.push
23
-
23
+
24
24
  # qu_job can be nil depending on the configured backend
25
25
  job.provider_job_id = qu_job.id unless qu_job.nil?
26
26
  qu_job
@@ -32,7 +32,7 @@ module ActiveJob
32
32
 
33
33
  class JobWrapper < Qu::Job #:nodoc:
34
34
  def initialize(job_data)
35
- @job_data = job_data
35
+ @job_data = job_data
36
36
  end
37
37
 
38
38
  def perform
@@ -1,4 +1,4 @@
1
- require 'que'
1
+ require "que"
2
2
 
3
3
  module ActiveJob
4
4
  module QueueAdapters
@@ -1,4 +1,4 @@
1
- require 'queue_classic'
1
+ require "queue_classic"
2
2
 
3
3
  module ActiveJob
4
4
  module QueueAdapters
@@ -26,9 +26,9 @@ module ActiveJob
26
26
  def enqueue_at(job, timestamp) #:nodoc:
27
27
  queue = build_queue(job.queue_name)
28
28
  unless queue.respond_to?(:enqueue_at)
29
- raise NotImplementedError, 'To be able to schedule jobs with queue_classic ' \
30
- 'the QC::Queue needs to respond to `enqueue_at(timestamp, method, *args)`. ' \
31
- 'You can implement this yourself or you can use the queue_classic-later gem.'
29
+ raise NotImplementedError, "To be able to schedule jobs with queue_classic " \
30
+ "the QC::Queue needs to respond to `enqueue_at(timestamp, method, *args)`. " \
31
+ "You can implement this yourself or you can use the queue_classic-later gem."
32
32
  end
33
33
  qc_job = queue.enqueue_at(timestamp, "#{JobWrapper.name}.perform", job.serialize)
34
34
  job.provider_job_id = qc_job["id"] if qc_job.is_a?(Hash)
@@ -1,12 +1,12 @@
1
- require 'resque'
2
- require 'active_support/core_ext/enumerable'
3
- require 'active_support/core_ext/array/access'
1
+ require "resque"
2
+ require "active_support/core_ext/enumerable"
3
+ require "active_support/core_ext/array/access"
4
4
 
5
5
  begin
6
- require 'resque-scheduler'
6
+ require "resque-scheduler"
7
7
  rescue LoadError
8
8
  begin
9
- require 'resque_scheduler'
9
+ require "resque_scheduler"
10
10
  rescue LoadError
11
11
  false
12
12
  end
@@ -1,4 +1,4 @@
1
- require 'sidekiq'
1
+ require "sidekiq"
2
2
 
3
3
  module ActiveJob
4
4
  module QueueAdapters
@@ -18,26 +18,26 @@ module ActiveJob
18
18
  def enqueue(job) #:nodoc:
19
19
  #Sidekiq::Client does not support symbols as keys
20
20
  job.provider_job_id = Sidekiq::Client.push \
21
- 'class' => JobWrapper,
22
- 'wrapped' => job.class.to_s,
23
- 'queue' => job.queue_name,
24
- 'args' => [ job.serialize ]
21
+ "class" => JobWrapper,
22
+ "wrapped" => job.class.to_s,
23
+ "queue" => job.queue_name,
24
+ "args" => [ job.serialize ]
25
25
  end
26
26
 
27
27
  def enqueue_at(job, timestamp) #:nodoc:
28
28
  job.provider_job_id = Sidekiq::Client.push \
29
- 'class' => JobWrapper,
30
- 'wrapped' => job.class.to_s,
31
- 'queue' => job.queue_name,
32
- 'args' => [ job.serialize ],
33
- 'at' => timestamp
29
+ "class" => JobWrapper,
30
+ "wrapped" => job.class.to_s,
31
+ "queue" => job.queue_name,
32
+ "args" => [ job.serialize ],
33
+ "at" => timestamp
34
34
  end
35
35
 
36
36
  class JobWrapper #:nodoc:
37
37
  include Sidekiq::Worker
38
38
 
39
39
  def perform(job_data)
40
- Base.execute job_data.merge('provider_job_id' => jid)
40
+ Base.execute job_data.merge("provider_job_id" => jid)
41
41
  end
42
42
  end
43
43
  end
@@ -1,5 +1,5 @@
1
- require 'sneakers'
2
- require 'monitor'
1
+ require "sneakers"
2
+ require "monitor"
3
3
 
4
4
  module ActiveJob
5
5
  module QueueAdapters
@@ -33,7 +33,7 @@ module ActiveJob
33
33
 
34
34
  class JobWrapper #:nodoc:
35
35
  include Sneakers::Worker
36
- from_queue 'default'
36
+ from_queue "default"
37
37
 
38
38
  def work(msg)
39
39
  job_data = ActiveSupport::JSON.decode(msg)
@@ -1,11 +1,11 @@
1
- require 'sucker_punch'
1
+ require "sucker_punch"
2
2
 
3
3
  module ActiveJob
4
4
  module QueueAdapters
5
5
  # == Sucker Punch adapter for Active Job
6
6
  #
7
7
  # Sucker Punch is a single-process Ruby asynchronous processing library.
8
- # This reduces the cost of of hosting on a service like Heroku along
8
+ # This reduces the cost of hosting on a service like Heroku along
9
9
  # with the memory footprint of having to maintain additional jobs if
10
10
  # hosting on a dedicated server. All queues can run within a
11
11
  # single application (eg. Rails, Sinatra, etc.) process.
@@ -31,7 +31,7 @@ module ActiveJob
31
31
  delay = timestamp - Time.current.to_f
32
32
  JobWrapper.perform_in delay, job.serialize
33
33
  else
34
- raise NotImplementedError, 'sucker_punch 1.0 does not support `enqueued_at`. Please upgrade to version ~> 2.0.0 to enable this behavior.'
34
+ raise NotImplementedError, "sucker_punch 1.0 does not support `enqueued_at`. Please upgrade to version ~> 2.0.0 to enable this behavior."
35
35
  end
36
36
  end
37
37
 
@@ -24,37 +24,33 @@ module ActiveJob
24
24
  end
25
25
 
26
26
  def enqueue(job) #:nodoc:
27
- return if filtered?(job)
28
-
29
27
  job_data = job_to_hash(job)
30
28
  enqueue_or_perform(perform_enqueued_jobs, job, job_data)
31
29
  end
32
30
 
33
31
  def enqueue_at(job, timestamp) #:nodoc:
34
- return if filtered?(job)
35
-
36
32
  job_data = job_to_hash(job, at: timestamp)
37
33
  enqueue_or_perform(perform_enqueued_at_jobs, job, job_data)
38
34
  end
39
35
 
40
36
  private
41
37
 
42
- def job_to_hash(job, extras = {})
43
- { job: job.class, args: job.serialize.fetch('arguments'), queue: job.queue_name }.merge!(extras)
44
- end
38
+ def job_to_hash(job, extras = {})
39
+ { job: job.class, args: job.serialize.fetch("arguments"), queue: job.queue_name }.merge!(extras)
40
+ end
45
41
 
46
- def enqueue_or_perform(perform, job, job_data)
47
- if perform
48
- performed_jobs << job_data
49
- Base.execute job.serialize
50
- else
51
- enqueued_jobs << job_data
42
+ def enqueue_or_perform(perform, job, job_data)
43
+ if !perform || filtered?(job)
44
+ enqueued_jobs << job_data
45
+ else
46
+ performed_jobs << job_data
47
+ Base.execute job.serialize
48
+ end
52
49
  end
53
- end
54
50
 
55
- def filtered?(job)
56
- filter && !Array(filter).include?(job.class)
57
- end
51
+ def filtered?(job)
52
+ filter && !Array(filter).include?(job.class)
53
+ end
58
54
  end
59
55
  end
60
56
  end
@@ -16,7 +16,7 @@ module ActiveJob
16
16
  # post.to_feed!
17
17
  # end
18
18
  # end
19
- def queue_as(part_name=nil, &block)
19
+ def queue_as(part_name = nil, &block)
20
20
  if block_given?
21
21
  self.queue_name = block
22
22
  else
@@ -36,7 +36,7 @@ module ActiveJob
36
36
  class_attribute :queue_name_delimiter, instance_accessor: false
37
37
 
38
38
  self.queue_name = default_queue_name
39
- self.queue_name_delimiter = '_' # set default delimiter to '_'
39
+ self.queue_name_delimiter = "_" # set default delimiter to '_'
40
40
  end
41
41
 
42
42
  # Returns the name of the queue the job will be run on.
@@ -46,6 +46,5 @@ module ActiveJob
46
46
  end
47
47
  @queue_name
48
48
  end
49
-
50
49
  end
51
50
  end
@@ -17,7 +17,7 @@ module ActiveJob
17
17
  # end
18
18
  #
19
19
  # Specify either an argument or a block.
20
- def queue_with_priority(priority=nil, &block)
20
+ def queue_with_priority(priority = nil, &block)
21
21
  if block_given?
22
22
  self.priority = block
23
23
  else
@@ -39,6 +39,5 @@ module ActiveJob
39
39
  end
40
40
  @priority
41
41
  end
42
-
43
42
  end
44
43
  end
@@ -1,12 +1,12 @@
1
- require 'global_id/railtie'
2
- require 'active_job'
1
+ require "global_id/railtie"
2
+ require "active_job"
3
3
 
4
4
  module ActiveJob
5
5
  # = Active Job Railtie
6
6
  class Railtie < Rails::Railtie # :nodoc:
7
7
  config.active_job = ActiveSupport::OrderedOptions.new
8
8
 
9
- initializer 'active_job.logger' do
9
+ initializer "active_job.logger" do
10
10
  ActiveSupport.on_load(:active_job) { self.logger = ::Rails.logger }
11
11
  end
12
12
 
@@ -15,7 +15,7 @@ module ActiveJob
15
15
  options.queue_adapter ||= :async
16
16
 
17
17
  ActiveSupport.on_load(:active_job) do
18
- options.each { |k,v| send("#{k}=", v) }
18
+ options.each { |k, v| send("#{k}=", v) }
19
19
  end
20
20
  end
21
21
 
@@ -1,4 +1,4 @@
1
- require 'active_support/test_case'
1
+ require "active_support/test_case"
2
2
 
3
3
  module ActiveJob
4
4
  class TestCase < ActiveSupport::TestCase
@@ -1,5 +1,5 @@
1
- require 'active_support/core_ext/class/subclasses'
2
- require 'active_support/core_ext/hash/keys'
1
+ require "active_support/core_ext/class/subclasses"
2
+ require "active_support/core_ext/hash/keys"
3
3
 
4
4
  module ActiveJob
5
5
  # Provides helper methods for testing Active Job
@@ -8,16 +8,35 @@ module ActiveJob
8
8
  :performed_jobs, :performed_jobs=,
9
9
  to: :queue_adapter
10
10
 
11
+ module TestQueueAdapter
12
+ extend ActiveSupport::Concern
13
+
14
+ included do
15
+ class_attribute :_test_adapter, instance_accessor: false, instance_predicate: false
16
+ end
17
+
18
+ module ClassMethods
19
+ def queue_adapter
20
+ self._test_adapter.nil? ? super : self._test_adapter
21
+ end
22
+
23
+ def disable_test_adapter
24
+ self._test_adapter = nil
25
+ end
26
+
27
+ def enable_test_adapter(test_adapter)
28
+ self._test_adapter = test_adapter
29
+ end
30
+ end
31
+ end
32
+
33
+ ActiveJob::Base.include(TestQueueAdapter)
34
+
11
35
  def before_setup # :nodoc:
12
36
  test_adapter = queue_adapter_for_test
13
37
 
14
- @old_queue_adapters = (ActiveJob::Base.descendants << ActiveJob::Base).select do |klass|
15
- # only override explicitly set adapters, a quirk of `class_attribute`
16
- klass.singleton_class.public_instance_methods(false).include?(:_queue_adapter)
17
- end.map do |klass|
18
- [klass, klass.queue_adapter].tap do
19
- klass.queue_adapter = test_adapter
20
- end
38
+ queue_adapter_changed_jobs.each do |klass|
39
+ klass.enable_test_adapter(test_adapter)
21
40
  end
22
41
 
23
42
  clear_enqueued_jobs
@@ -27,9 +46,8 @@ module ActiveJob
27
46
 
28
47
  def after_teardown # :nodoc:
29
48
  super
30
- @old_queue_adapters.each do |(klass, adapter)|
31
- klass.queue_adapter = adapter
32
- end
49
+
50
+ queue_adapter_changed_jobs.each { |klass| klass.disable_test_adapter }
33
51
  end
34
52
 
35
53
  # Specifies the queue adapter to use with all active job test helpers.
@@ -55,7 +73,7 @@ module ActiveJob
55
73
  # assert_enqueued_jobs 2
56
74
  # end
57
75
  #
58
- # If a block is passed, that block should cause the specified number of
76
+ # If a block is passed, that block will cause the specified number of
59
77
  # jobs to be enqueued.
60
78
  #
61
79
  # def test_jobs_again
@@ -77,14 +95,23 @@ module ActiveJob
77
95
  # HelloJob.perform_later('jeremy')
78
96
  # end
79
97
  # end
80
- def assert_enqueued_jobs(number, only: nil)
98
+ #
99
+ # The number of times a job is enqueued to a specific queue can also be asserted.
100
+ #
101
+ # def test_logging_job
102
+ # assert_enqueued_jobs 2, queue: 'default' do
103
+ # LoggingJob.perform_later
104
+ # HelloJob.perform_later('elfassy')
105
+ # end
106
+ # end
107
+ def assert_enqueued_jobs(number, only: nil, queue: nil)
81
108
  if block_given?
82
- original_count = enqueued_jobs_size(only: only)
109
+ original_count = enqueued_jobs_size(only: only, queue: queue)
83
110
  yield
84
- new_count = enqueued_jobs_size(only: only)
111
+ new_count = enqueued_jobs_size(only: only, queue: queue)
85
112
  assert_equal number, new_count - original_count, "#{number} jobs expected, but #{new_count - original_count} were enqueued"
86
113
  else
87
- actual_count = enqueued_jobs_size(only: only)
114
+ actual_count = enqueued_jobs_size(only: only, queue: queue)
88
115
  assert_equal number, actual_count, "#{number} jobs expected, but #{actual_count} were enqueued"
89
116
  end
90
117
  end
@@ -232,16 +259,16 @@ module ActiveJob
232
259
  # MyJob.set(wait_until: Date.tomorrow.noon).perform_later
233
260
  # end
234
261
  # end
235
- def assert_enqueued_with(args = {})
262
+ def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil)
236
263
  original_enqueued_jobs_count = enqueued_jobs.count
237
- args.assert_valid_keys(:job, :args, :at, :queue)
238
- serialized_args = serialize_args_for_assertion(args)
264
+ expected = { job: job, args: args, at: at, queue: queue }.compact
265
+ serialized_args = serialize_args_for_assertion(expected)
239
266
  yield
240
267
  in_block_jobs = enqueued_jobs.drop(original_enqueued_jobs_count)
241
- matching_job = in_block_jobs.find do |job|
242
- serialized_args.all? { |key, value| value == job[key] }
268
+ matching_job = in_block_jobs.find do |in_block_job|
269
+ serialized_args.all? { |key, value| value == in_block_job[key] }
243
270
  end
244
- assert matching_job, "No enqueued job found with #{args}"
271
+ assert matching_job, "No enqueued job found with #{expected}"
245
272
  instantiate_job(matching_job)
246
273
  end
247
274
 
@@ -256,16 +283,16 @@ module ActiveJob
256
283
  # MyJob.set(wait_until: Date.tomorrow.noon).perform_later
257
284
  # end
258
285
  # end
259
- def assert_performed_with(args = {})
286
+ def assert_performed_with(job: nil, args: nil, at: nil, queue: nil)
260
287
  original_performed_jobs_count = performed_jobs.count
261
- args.assert_valid_keys(:job, :args, :at, :queue)
262
- serialized_args = serialize_args_for_assertion(args)
288
+ expected = { job: job, args: args, at: at, queue: queue }.compact
289
+ serialized_args = serialize_args_for_assertion(expected)
263
290
  perform_enqueued_jobs { yield }
264
291
  in_block_jobs = performed_jobs.drop(original_performed_jobs_count)
265
- matching_job = in_block_jobs.find do |job|
266
- serialized_args.all? { |key, value| value == job[key] }
292
+ matching_job = in_block_jobs.find do |in_block_job|
293
+ serialized_args.all? { |key, value| value == in_block_job[key] }
267
294
  end
268
- assert matching_job, "No performed job found with #{args}"
295
+ assert matching_job, "No performed job found with #{expected}"
269
296
  instantiate_job(matching_job)
270
297
  end
271
298
 
@@ -284,7 +311,7 @@ module ActiveJob
284
311
  # def test_perform_enqueued_jobs_with_only
285
312
  # perform_enqueued_jobs(only: MyJob) do
286
313
  # MyJob.perform_later(1, 2, 3) # will be performed
287
- # HelloJob.perform_later(1, 2, 3) # will not be perfomed
314
+ # HelloJob.perform_later(1, 2, 3) # will not be performed
288
315
  # end
289
316
  # assert_performed_jobs 1
290
317
  # end
@@ -315,34 +342,46 @@ module ActiveJob
315
342
  end
316
343
 
317
344
  private
318
- def clear_enqueued_jobs # :nodoc:
345
+ def clear_enqueued_jobs
319
346
  enqueued_jobs.clear
320
347
  end
321
348
 
322
- def clear_performed_jobs # :nodoc:
349
+ def clear_performed_jobs
323
350
  performed_jobs.clear
324
351
  end
325
352
 
326
- def enqueued_jobs_size(only: nil) # :nodoc:
327
- if only
328
- enqueued_jobs.count { |job| Array(only).include?(job.fetch(:job)) }
329
- else
330
- enqueued_jobs.count
353
+ def enqueued_jobs_size(only: nil, queue: nil)
354
+ enqueued_jobs.count do |job|
355
+ job_class = job.fetch(:job)
356
+ if only
357
+ next false unless Array(only).include?(job_class)
358
+ end
359
+ if queue
360
+ next false unless queue.to_s == job.fetch(:queue, job_class.queue_name)
361
+ end
362
+ true
331
363
  end
332
364
  end
333
365
 
334
- def serialize_args_for_assertion(args) # :nodoc:
366
+ def serialize_args_for_assertion(args)
335
367
  args.dup.tap do |serialized_args|
336
368
  serialized_args[:args] = ActiveJob::Arguments.serialize(serialized_args[:args]) if serialized_args[:args]
337
369
  serialized_args[:at] = serialized_args[:at].to_f if serialized_args[:at]
338
370
  end
339
371
  end
340
372
 
341
- def instantiate_job(payload) # :nodoc:
373
+ def instantiate_job(payload)
342
374
  job = payload[:job].new(*payload[:args])
343
375
  job.scheduled_at = Time.at(payload[:at]) if payload.key?(:at)
344
376
  job.queue_name = payload[:queue]
345
377
  job
346
378
  end
379
+
380
+ def queue_adapter_changed_jobs
381
+ (ActiveJob::Base.descendants << ActiveJob::Base).select do |klass|
382
+ # only override explicitly set adapters, a quirk of `class_attribute`
383
+ klass.singleton_class.public_instance_methods(false).include?(:_queue_adapter)
384
+ end
385
+ end
347
386
  end
348
387
  end