activejob 6.0.3.3 → 6.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +82 -149
- data/MIT-LICENSE +1 -1
- data/README.md +1 -3
- data/lib/active_job.rb +1 -1
- data/lib/active_job/base.rb +3 -0
- data/lib/active_job/callbacks.rb +44 -4
- data/lib/active_job/core.rb +3 -2
- data/lib/active_job/enqueuing.rb +3 -13
- data/lib/active_job/exceptions.rb +29 -20
- data/lib/active_job/execution.rb +9 -1
- data/lib/active_job/gem_version.rb +3 -3
- data/lib/active_job/instrumentation.rb +40 -0
- data/lib/active_job/log_subscriber.rb +140 -0
- data/lib/active_job/logging.rb +3 -132
- data/lib/active_job/queue_adapter.rb +3 -0
- data/lib/active_job/queue_adapters.rb +5 -1
- data/lib/active_job/queue_adapters/sucker_punch_adapter.rb +1 -1
- data/lib/active_job/queue_adapters/test_adapter.rb +6 -2
- data/lib/active_job/queue_name.rb +2 -2
- data/lib/active_job/railtie.rb +4 -0
- data/lib/active_job/serializers.rb +4 -1
- data/lib/active_job/serializers/date_time_serializer.rb +1 -5
- data/lib/active_job/serializers/module_serializer.rb +20 -0
- data/lib/active_job/serializers/object_serializer.rb +1 -1
- data/lib/active_job/serializers/time_object_serializer.rb +13 -0
- data/lib/active_job/serializers/time_serializer.rb +1 -5
- data/lib/active_job/serializers/time_with_zone_serializer.rb +1 -5
- data/lib/active_job/test_helper.rb +81 -80
- metadata +15 -11
@@ -11,6 +11,9 @@ module ActiveJob
|
|
11
11
|
included do
|
12
12
|
class_attribute :_queue_adapter_name, instance_accessor: false, instance_predicate: false
|
13
13
|
class_attribute :_queue_adapter, instance_accessor: false, instance_predicate: false
|
14
|
+
|
15
|
+
delegate :queue_adapter, to: :class
|
16
|
+
|
14
17
|
self.queue_adapter = :async
|
15
18
|
end
|
16
19
|
|
@@ -72,7 +72,7 @@ module ActiveJob
|
|
72
72
|
# Yes: Allows the priority to be set on the job object, at the queue level or
|
73
73
|
# as default configuration option.
|
74
74
|
#
|
75
|
-
# No:
|
75
|
+
# No: The adapter does not allow the priority of jobs to be configured.
|
76
76
|
#
|
77
77
|
# N/A: The adapter does not support queuing, and therefore sorting them.
|
78
78
|
#
|
@@ -86,6 +86,8 @@ module ActiveJob
|
|
86
86
|
#
|
87
87
|
# Global: The adapter is configured that all jobs have a maximum run time.
|
88
88
|
#
|
89
|
+
# No: The adapter does not allow the timeout of jobs to be configured.
|
90
|
+
#
|
89
91
|
# N/A: This adapter does not run in a separate process, and therefore timeout
|
90
92
|
# is unsupported.
|
91
93
|
#
|
@@ -99,6 +101,8 @@ module ActiveJob
|
|
99
101
|
#
|
100
102
|
# Global: The adapter has a global number of retries.
|
101
103
|
#
|
104
|
+
# No: The adapter does not allow the number of retries to be configured.
|
105
|
+
#
|
102
106
|
# N/A: The adapter does not run in a separate process, and therefore doesn't
|
103
107
|
# support retries.
|
104
108
|
#
|
@@ -10,7 +10,7 @@ module ActiveJob
|
|
10
10
|
# This reduces the cost of hosting on a service like Heroku along
|
11
11
|
# with the memory footprint of having to maintain additional jobs if
|
12
12
|
# hosting on a dedicated server. All queues can run within a
|
13
|
-
# single application (
|
13
|
+
# single application (e.g. Rails, Sinatra, etc.) process.
|
14
14
|
#
|
15
15
|
# Read more about Sucker Punch {here}[https://github.com/brandonhilkert/sucker_punch].
|
16
16
|
#
|
@@ -12,7 +12,7 @@ module ActiveJob
|
|
12
12
|
#
|
13
13
|
# Rails.application.config.active_job.queue_adapter = :test
|
14
14
|
class TestAdapter
|
15
|
-
attr_accessor(:perform_enqueued_jobs, :perform_enqueued_at_jobs, :filter, :reject, :queue)
|
15
|
+
attr_accessor(:perform_enqueued_jobs, :perform_enqueued_at_jobs, :filter, :reject, :queue, :at)
|
16
16
|
attr_writer(:enqueued_jobs, :performed_jobs)
|
17
17
|
|
18
18
|
# Provides a store of all the enqueued jobs with the TestAdapter so you can check them.
|
@@ -54,7 +54,11 @@ module ActiveJob
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def filtered?(job)
|
57
|
-
filtered_queue?(job) || filtered_job_class?(job)
|
57
|
+
filtered_queue?(job) || filtered_job_class?(job) || filtered_time?(job)
|
58
|
+
end
|
59
|
+
|
60
|
+
def filtered_time?(job)
|
61
|
+
job.scheduled_at > at.to_f if at && job.scheduled_at
|
58
62
|
end
|
59
63
|
|
60
64
|
def filtered_queue?(job)
|
@@ -6,7 +6,6 @@ module ActiveJob
|
|
6
6
|
|
7
7
|
# Includes the ability to override the default queue name and prefix.
|
8
8
|
module ClassMethods
|
9
|
-
mattr_accessor :queue_name_prefix
|
10
9
|
mattr_accessor :default_queue_name, default: "default"
|
11
10
|
|
12
11
|
# Specifies the name of the queue to process the job on.
|
@@ -49,13 +48,14 @@ module ActiveJob
|
|
49
48
|
def queue_name_from_part(part_name) #:nodoc:
|
50
49
|
queue_name = part_name || default_queue_name
|
51
50
|
name_parts = [queue_name_prefix.presence, queue_name]
|
52
|
-
name_parts.compact.join(queue_name_delimiter)
|
51
|
+
-name_parts.compact.join(queue_name_delimiter)
|
53
52
|
end
|
54
53
|
end
|
55
54
|
|
56
55
|
included do
|
57
56
|
class_attribute :queue_name, instance_accessor: false, default: -> { self.class.default_queue_name }
|
58
57
|
class_attribute :queue_name_delimiter, instance_accessor: false, default: "_"
|
58
|
+
class_attribute :queue_name_prefix
|
59
59
|
end
|
60
60
|
|
61
61
|
# Returns the name of the queue the job will be run on.
|
data/lib/active_job/railtie.rb
CHANGED
@@ -34,6 +34,10 @@ module ActiveJob
|
|
34
34
|
ActiveSupport.on_load(:action_dispatch_integration_test) do
|
35
35
|
include ActiveJob::TestHelper
|
36
36
|
end
|
37
|
+
|
38
|
+
ActiveSupport.on_load(:active_record) do
|
39
|
+
self.destroy_association_async_job = ActiveRecord::DestroyAssociationAsyncJob
|
40
|
+
end
|
37
41
|
end
|
38
42
|
|
39
43
|
initializer "active_job.set_reloader_hook" do |app|
|
@@ -9,12 +9,14 @@ module ActiveJob
|
|
9
9
|
extend ActiveSupport::Autoload
|
10
10
|
|
11
11
|
autoload :ObjectSerializer
|
12
|
+
autoload :TimeObjectSerializer
|
12
13
|
autoload :SymbolSerializer
|
13
14
|
autoload :DurationSerializer
|
14
15
|
autoload :DateTimeSerializer
|
15
16
|
autoload :DateSerializer
|
16
17
|
autoload :TimeWithZoneSerializer
|
17
18
|
autoload :TimeSerializer
|
19
|
+
autoload :ModuleSerializer
|
18
20
|
|
19
21
|
mattr_accessor :_additional_serializers
|
20
22
|
self._additional_serializers = Set.new
|
@@ -58,6 +60,7 @@ module ActiveJob
|
|
58
60
|
DateTimeSerializer,
|
59
61
|
DateSerializer,
|
60
62
|
TimeWithZoneSerializer,
|
61
|
-
TimeSerializer
|
63
|
+
TimeSerializer,
|
64
|
+
ModuleSerializer
|
62
65
|
end
|
63
66
|
end
|
@@ -2,11 +2,7 @@
|
|
2
2
|
|
3
3
|
module ActiveJob
|
4
4
|
module Serializers
|
5
|
-
class DateTimeSerializer <
|
6
|
-
def serialize(time)
|
7
|
-
super("value" => time.iso8601)
|
8
|
-
end
|
9
|
-
|
5
|
+
class DateTimeSerializer < TimeObjectSerializer # :nodoc:
|
10
6
|
def deserialize(hash)
|
11
7
|
DateTime.iso8601(hash["value"])
|
12
8
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveJob
|
4
|
+
module Serializers
|
5
|
+
class ModuleSerializer < ObjectSerializer # :nodoc:
|
6
|
+
def serialize(constant)
|
7
|
+
super("value" => constant.name)
|
8
|
+
end
|
9
|
+
|
10
|
+
def deserialize(hash)
|
11
|
+
hash["value"].constantize
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
def klass
|
16
|
+
Module
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -2,11 +2,7 @@
|
|
2
2
|
|
3
3
|
module ActiveJob
|
4
4
|
module Serializers
|
5
|
-
class TimeSerializer <
|
6
|
-
def serialize(time)
|
7
|
-
super("value" => time.iso8601)
|
8
|
-
end
|
9
|
-
|
5
|
+
class TimeSerializer < TimeObjectSerializer # :nodoc:
|
10
6
|
def deserialize(hash)
|
11
7
|
Time.iso8601(hash["value"])
|
12
8
|
end
|
@@ -2,11 +2,7 @@
|
|
2
2
|
|
3
3
|
module ActiveJob
|
4
4
|
module Serializers
|
5
|
-
class TimeWithZoneSerializer <
|
6
|
-
def serialize(time)
|
7
|
-
super("value" => time.iso8601)
|
8
|
-
end
|
9
|
-
|
5
|
+
class TimeWithZoneSerializer < TimeObjectSerializer # :nodoc:
|
10
6
|
def deserialize(hash)
|
11
7
|
Time.iso8601(hash["value"]).in_time_zone
|
12
8
|
end
|
@@ -9,6 +9,8 @@ module ActiveJob
|
|
9
9
|
:performed_jobs, :performed_jobs=,
|
10
10
|
to: :queue_adapter
|
11
11
|
|
12
|
+
include ActiveSupport::Testing::Assertions
|
13
|
+
|
12
14
|
module TestQueueAdapter
|
13
15
|
extend ActiveSupport::Concern
|
14
16
|
|
@@ -117,17 +119,17 @@ module ActiveJob
|
|
117
119
|
# HelloJob.perform_later('elfassy')
|
118
120
|
# end
|
119
121
|
# end
|
120
|
-
def assert_enqueued_jobs(number, only: nil, except: nil, queue: nil)
|
122
|
+
def assert_enqueued_jobs(number, only: nil, except: nil, queue: nil, &block)
|
121
123
|
if block_given?
|
122
|
-
|
124
|
+
original_jobs = enqueued_jobs_with(only: only, except: except, queue: queue)
|
123
125
|
|
124
|
-
|
126
|
+
assert_nothing_raised(&block)
|
125
127
|
|
126
|
-
|
128
|
+
new_jobs = enqueued_jobs_with(only: only, except: except, queue: queue)
|
127
129
|
|
128
|
-
actual_count =
|
130
|
+
actual_count = (new_jobs - original_jobs).count
|
129
131
|
else
|
130
|
-
actual_count = enqueued_jobs_with(only: only, except: except, queue: queue)
|
132
|
+
actual_count = enqueued_jobs_with(only: only, except: except, queue: queue).count
|
131
133
|
end
|
132
134
|
|
133
135
|
assert_equal number, actual_count, "#{number} jobs expected, but #{actual_count} were enqueued"
|
@@ -279,7 +281,7 @@ module ActiveJob
|
|
279
281
|
|
280
282
|
performed_jobs_size = new_count - original_count
|
281
283
|
else
|
282
|
-
performed_jobs_size = performed_jobs_with(only: only, except: except, queue: queue)
|
284
|
+
performed_jobs_size = performed_jobs_with(only: only, except: except, queue: queue).count
|
283
285
|
end
|
284
286
|
|
285
287
|
assert_equal number, performed_jobs_size, "#{number} jobs expected, but #{performed_jobs_size} were performed"
|
@@ -345,44 +347,40 @@ module ActiveJob
|
|
345
347
|
#
|
346
348
|
# def test_assert_enqueued_with
|
347
349
|
# MyJob.perform_later(1,2,3)
|
348
|
-
# assert_enqueued_with(job: MyJob, args: [1,2,3]
|
350
|
+
# assert_enqueued_with(job: MyJob, args: [1,2,3])
|
349
351
|
#
|
350
|
-
# MyJob.set(wait_until: Date.tomorrow.noon).perform_later
|
351
|
-
# assert_enqueued_with(
|
352
|
+
# MyJob.set(wait_until: Date.tomorrow.noon, queue: "my_queue").perform_later
|
353
|
+
# assert_enqueued_with(at: Date.tomorrow.noon, queue: "my_queue")
|
352
354
|
# end
|
353
355
|
#
|
354
|
-
# The
|
356
|
+
# The given arguments may also be specified as matcher procs that return a
|
357
|
+
# boolean value indicating whether a job's attribute meets certain criteria.
|
355
358
|
#
|
356
|
-
#
|
359
|
+
# For example, a proc can be used to match a range of times:
|
357
360
|
#
|
358
361
|
# def test_assert_enqueued_with
|
359
|
-
#
|
360
|
-
#
|
361
|
-
#
|
362
|
+
# at_matcher = ->(job_at) { (Date.yesterday..Date.tomorrow).cover?(job_at) }
|
363
|
+
#
|
364
|
+
# MyJob.set(wait_until: Date.today.noon).perform_later
|
362
365
|
#
|
363
|
-
# MyJob
|
364
|
-
# assert_enqueued_with(job: MyJob, at: expected_time)
|
366
|
+
# assert_enqueued_with(job: MyJob, at: at_matcher)
|
365
367
|
# end
|
366
368
|
#
|
367
|
-
#
|
368
|
-
# Your proc needs to return a boolean value determining if
|
369
|
-
# the job's arguments matches your expectation. This is useful to check only
|
370
|
-
# for a subset of arguments.
|
369
|
+
# A proc can also be used to match a subset of a job's args:
|
371
370
|
#
|
372
371
|
# def test_assert_enqueued_with
|
373
|
-
#
|
374
|
-
#
|
375
|
-
#
|
372
|
+
# args_matcher = ->(job_args) { job_args[0].key?(:foo) }
|
373
|
+
#
|
374
|
+
# MyJob.perform_later(foo: "bar", other_arg: "No need to check in the test")
|
376
375
|
#
|
377
|
-
#
|
378
|
-
# assert_enqueued_with(job: MyJob, args: expected_args, queue: 'low')
|
376
|
+
# assert_enqueued_with(job: MyJob, args: args_matcher)
|
379
377
|
# end
|
380
378
|
#
|
381
379
|
# If a block is passed, asserts that the block will cause the job to be
|
382
380
|
# enqueued with the given arguments.
|
383
381
|
#
|
384
382
|
# def test_assert_enqueued_with
|
385
|
-
# assert_enqueued_with(job: MyJob, args: [1,2,3]
|
383
|
+
# assert_enqueued_with(job: MyJob, args: [1,2,3]) do
|
386
384
|
# MyJob.perform_later(1,2,3)
|
387
385
|
# end
|
388
386
|
#
|
@@ -390,22 +388,24 @@ module ActiveJob
|
|
390
388
|
# MyJob.set(wait_until: Date.tomorrow.noon).perform_later
|
391
389
|
# end
|
392
390
|
# end
|
393
|
-
def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil)
|
391
|
+
def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil, &block)
|
394
392
|
expected = { job: job, args: args, at: at, queue: queue }.compact
|
395
393
|
expected_args = prepare_args_for_assertion(expected)
|
394
|
+
potential_matches = []
|
396
395
|
|
397
396
|
if block_given?
|
398
|
-
|
397
|
+
original_enqueued_jobs = enqueued_jobs.dup
|
399
398
|
|
400
|
-
|
399
|
+
assert_nothing_raised(&block)
|
401
400
|
|
402
|
-
jobs = enqueued_jobs
|
401
|
+
jobs = enqueued_jobs - original_enqueued_jobs
|
403
402
|
else
|
404
403
|
jobs = enqueued_jobs
|
405
404
|
end
|
406
405
|
|
407
406
|
matching_job = jobs.find do |enqueued_job|
|
408
407
|
deserialized_job = deserialize_args_for_assertion(enqueued_job)
|
408
|
+
potential_matches << deserialized_job
|
409
409
|
|
410
410
|
expected_args.all? do |key, value|
|
411
411
|
if value.respond_to?(:call)
|
@@ -416,7 +416,9 @@ module ActiveJob
|
|
416
416
|
end
|
417
417
|
end
|
418
418
|
|
419
|
-
|
419
|
+
message = +"No enqueued job found with #{expected}"
|
420
|
+
message << "\n\nPotential matches: #{potential_matches.join("\n")}" if potential_matches.present?
|
421
|
+
assert matching_job, message
|
420
422
|
instantiate_job(matching_job)
|
421
423
|
end
|
422
424
|
|
@@ -427,42 +429,40 @@ module ActiveJob
|
|
427
429
|
#
|
428
430
|
# perform_enqueued_jobs
|
429
431
|
#
|
430
|
-
# assert_performed_with(job: MyJob, args: [1,2,3]
|
432
|
+
# assert_performed_with(job: MyJob, args: [1,2,3])
|
431
433
|
#
|
432
|
-
# MyJob.set(wait_until: Date.tomorrow.noon).perform_later
|
434
|
+
# MyJob.set(wait_until: Date.tomorrow.noon, queue: "my_queue").perform_later
|
433
435
|
#
|
434
436
|
# perform_enqueued_jobs
|
435
437
|
#
|
436
|
-
# assert_performed_with(
|
438
|
+
# assert_performed_with(at: Date.tomorrow.noon, queue: "my_queue")
|
437
439
|
# end
|
438
440
|
#
|
439
|
-
# The
|
441
|
+
# The given arguments may also be specified as matcher procs that return a
|
442
|
+
# boolean value indicating whether a job's attribute meets certain criteria.
|
440
443
|
#
|
441
|
-
#
|
444
|
+
# For example, a proc can be used to match a range of times:
|
442
445
|
#
|
443
|
-
# def
|
444
|
-
#
|
445
|
-
#
|
446
|
-
#
|
446
|
+
# def test_assert_performed_with
|
447
|
+
# at_matcher = ->(job_at) { (Date.yesterday..Date.tomorrow).cover?(job_at) }
|
448
|
+
#
|
449
|
+
# MyJob.set(wait_until: Date.today.noon).perform_later
|
450
|
+
#
|
451
|
+
# perform_enqueued_jobs
|
447
452
|
#
|
448
|
-
# MyJob
|
449
|
-
# assert_enqueued_with(job: MyJob, at: expected_time)
|
453
|
+
# assert_performed_with(job: MyJob, at: at_matcher)
|
450
454
|
# end
|
451
455
|
#
|
452
|
-
#
|
453
|
-
# Your proc needs to return a boolean value determining if
|
454
|
-
# the job's arguments matches your expectation. This is useful to check only
|
455
|
-
# for a subset of arguments.
|
456
|
+
# A proc can also be used to match a subset of a job's args:
|
456
457
|
#
|
457
458
|
# def test_assert_performed_with
|
458
|
-
#
|
459
|
-
#
|
460
|
-
#
|
461
|
-
# MyJob.perform_later(foo: 'bar', other_arg: 'No need to check in the test')
|
459
|
+
# args_matcher = ->(job_args) { job_args[0].key?(:foo) }
|
460
|
+
#
|
461
|
+
# MyJob.perform_later(foo: "bar", other_arg: "No need to check in the test")
|
462
462
|
#
|
463
463
|
# perform_enqueued_jobs
|
464
464
|
#
|
465
|
-
# assert_performed_with(job: MyJob, args:
|
465
|
+
# assert_performed_with(job: MyJob, args: args_matcher)
|
466
466
|
# end
|
467
467
|
#
|
468
468
|
# If a block is passed, that block performs all of the jobs that were
|
@@ -470,7 +470,7 @@ module ActiveJob
|
|
470
470
|
# the job has been performed with the given arguments in the block.
|
471
471
|
#
|
472
472
|
# def test_assert_performed_with
|
473
|
-
# assert_performed_with(job: MyJob, args: [1,2,3]
|
473
|
+
# assert_performed_with(job: MyJob, args: [1,2,3]) do
|
474
474
|
# MyJob.perform_later(1,2,3)
|
475
475
|
# end
|
476
476
|
#
|
@@ -481,6 +481,7 @@ module ActiveJob
|
|
481
481
|
def assert_performed_with(job: nil, args: nil, at: nil, queue: nil, &block)
|
482
482
|
expected = { job: job, args: args, at: at, queue: queue }.compact
|
483
483
|
expected_args = prepare_args_for_assertion(expected)
|
484
|
+
potential_matches = []
|
484
485
|
|
485
486
|
if block_given?
|
486
487
|
original_performed_jobs_count = performed_jobs.count
|
@@ -494,6 +495,7 @@ module ActiveJob
|
|
494
495
|
|
495
496
|
matching_job = jobs.find do |enqueued_job|
|
496
497
|
deserialized_job = deserialize_args_for_assertion(enqueued_job)
|
498
|
+
potential_matches << deserialized_job
|
497
499
|
|
498
500
|
expected_args.all? do |key, value|
|
499
501
|
if value.respond_to?(:call)
|
@@ -504,7 +506,10 @@ module ActiveJob
|
|
504
506
|
end
|
505
507
|
end
|
506
508
|
|
507
|
-
|
509
|
+
message = +"No performed job found with #{expected}"
|
510
|
+
message << "\n\nPotential matches: #{potential_matches.join("\n")}" if potential_matches.present?
|
511
|
+
assert matching_job, message
|
512
|
+
|
508
513
|
instantiate_job(matching_job)
|
509
514
|
end
|
510
515
|
|
@@ -563,8 +568,10 @@ module ActiveJob
|
|
563
568
|
# assert_performed_jobs 1
|
564
569
|
# end
|
565
570
|
#
|
566
|
-
|
567
|
-
|
571
|
+
# If the +:at+ option is specified, then only run jobs enqueued to run
|
572
|
+
# immediately or before the given time
|
573
|
+
def perform_enqueued_jobs(only: nil, except: nil, queue: nil, at: nil, &block)
|
574
|
+
return flush_enqueued_jobs(only: only, except: except, queue: queue, at: at) unless block_given?
|
568
575
|
|
569
576
|
validate_option(only: only, except: except)
|
570
577
|
|
@@ -573,6 +580,7 @@ module ActiveJob
|
|
573
580
|
old_filter = queue_adapter.filter
|
574
581
|
old_reject = queue_adapter.reject
|
575
582
|
old_queue = queue_adapter.queue
|
583
|
+
old_at = queue_adapter.at
|
576
584
|
|
577
585
|
begin
|
578
586
|
queue_adapter.perform_enqueued_jobs = true
|
@@ -580,14 +588,16 @@ module ActiveJob
|
|
580
588
|
queue_adapter.filter = only
|
581
589
|
queue_adapter.reject = except
|
582
590
|
queue_adapter.queue = queue
|
591
|
+
queue_adapter.at = at
|
583
592
|
|
584
|
-
|
593
|
+
assert_nothing_raised(&block)
|
585
594
|
ensure
|
586
595
|
queue_adapter.perform_enqueued_jobs = old_perform_enqueued_jobs
|
587
596
|
queue_adapter.perform_enqueued_at_jobs = old_perform_enqueued_at_jobs
|
588
597
|
queue_adapter.filter = old_filter
|
589
598
|
queue_adapter.reject = old_reject
|
590
599
|
queue_adapter.queue = old_queue
|
600
|
+
queue_adapter.at = old_at
|
591
601
|
end
|
592
602
|
end
|
593
603
|
|
@@ -609,10 +619,10 @@ module ActiveJob
|
|
609
619
|
performed_jobs.clear
|
610
620
|
end
|
611
621
|
|
612
|
-
def jobs_with(jobs, only: nil, except: nil, queue: nil)
|
622
|
+
def jobs_with(jobs, only: nil, except: nil, queue: nil, at: nil)
|
613
623
|
validate_option(only: only, except: except)
|
614
624
|
|
615
|
-
jobs.
|
625
|
+
jobs.dup.select do |job|
|
616
626
|
job_class = job.fetch(:job)
|
617
627
|
|
618
628
|
if only
|
@@ -625,6 +635,10 @@ module ActiveJob
|
|
625
635
|
next false unless queue.to_s == job.fetch(:queue, job_class.queue_name)
|
626
636
|
end
|
627
637
|
|
638
|
+
if at && job[:at]
|
639
|
+
next false if job[:at] > at.to_f
|
640
|
+
end
|
641
|
+
|
628
642
|
yield job if block_given?
|
629
643
|
|
630
644
|
true
|
@@ -637,41 +651,28 @@ module ActiveJob
|
|
637
651
|
->(job) { Array(filter).include?(job.fetch(:job)) }
|
638
652
|
end
|
639
653
|
|
640
|
-
def enqueued_jobs_with(only: nil, except: nil, queue: nil, &block)
|
641
|
-
jobs_with(enqueued_jobs, only: only, except: except, queue: queue, &block)
|
654
|
+
def enqueued_jobs_with(only: nil, except: nil, queue: nil, at: nil, &block)
|
655
|
+
jobs_with(enqueued_jobs, only: only, except: except, queue: queue, at: at, &block)
|
642
656
|
end
|
643
657
|
|
644
658
|
def performed_jobs_with(only: nil, except: nil, queue: nil, &block)
|
645
659
|
jobs_with(performed_jobs, only: only, except: except, queue: queue, &block)
|
646
660
|
end
|
647
661
|
|
648
|
-
def flush_enqueued_jobs(only: nil, except: nil, queue: nil)
|
649
|
-
enqueued_jobs_with(only: only, except: except, queue: queue) do |payload|
|
650
|
-
|
662
|
+
def flush_enqueued_jobs(only: nil, except: nil, queue: nil, at: nil)
|
663
|
+
enqueued_jobs_with(only: only, except: except, queue: queue, at: at) do |payload|
|
664
|
+
queue_adapter.enqueued_jobs.delete(payload)
|
651
665
|
queue_adapter.performed_jobs << payload
|
652
|
-
|
666
|
+
instantiate_job(payload).perform_now
|
667
|
+
end.count
|
653
668
|
end
|
654
669
|
|
655
670
|
def prepare_args_for_assertion(args)
|
656
671
|
args.dup.tap do |arguments|
|
657
|
-
if arguments[:at]
|
672
|
+
if arguments[:at].acts_like?(:time)
|
658
673
|
at_range = arguments[:at] - 1..arguments[:at] + 1
|
659
674
|
arguments[:at] = ->(at) { at_range.cover?(at) }
|
660
675
|
end
|
661
|
-
arguments[:args] = round_time_arguments(arguments[:args]) if arguments[:args]
|
662
|
-
end
|
663
|
-
end
|
664
|
-
|
665
|
-
def round_time_arguments(argument)
|
666
|
-
case argument
|
667
|
-
when Time, ActiveSupport::TimeWithZone, DateTime
|
668
|
-
argument.change(usec: 0)
|
669
|
-
when Hash
|
670
|
-
argument.transform_values { |value| round_time_arguments(value) }
|
671
|
-
when Array
|
672
|
-
argument.map { |element| round_time_arguments(element) }
|
673
|
-
else
|
674
|
-
argument
|
675
676
|
end
|
676
677
|
end
|
677
678
|
|