activejob 6.0.3.2 → 6.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +74 -147
- 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 +37 -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 +79 -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
|
@@ -117,17 +117,17 @@ module ActiveJob
|
|
117
117
|
# HelloJob.perform_later('elfassy')
|
118
118
|
# end
|
119
119
|
# end
|
120
|
-
def assert_enqueued_jobs(number, only: nil, except: nil, queue: nil)
|
120
|
+
def assert_enqueued_jobs(number, only: nil, except: nil, queue: nil, &block)
|
121
121
|
if block_given?
|
122
|
-
|
122
|
+
original_jobs = enqueued_jobs_with(only: only, except: except, queue: queue)
|
123
123
|
|
124
|
-
|
124
|
+
assert_nothing_raised(&block)
|
125
125
|
|
126
|
-
|
126
|
+
new_jobs = enqueued_jobs_with(only: only, except: except, queue: queue)
|
127
127
|
|
128
|
-
actual_count =
|
128
|
+
actual_count = (new_jobs - original_jobs).count
|
129
129
|
else
|
130
|
-
actual_count = enqueued_jobs_with(only: only, except: except, queue: queue)
|
130
|
+
actual_count = enqueued_jobs_with(only: only, except: except, queue: queue).count
|
131
131
|
end
|
132
132
|
|
133
133
|
assert_equal number, actual_count, "#{number} jobs expected, but #{actual_count} were enqueued"
|
@@ -279,7 +279,7 @@ module ActiveJob
|
|
279
279
|
|
280
280
|
performed_jobs_size = new_count - original_count
|
281
281
|
else
|
282
|
-
performed_jobs_size = performed_jobs_with(only: only, except: except, queue: queue)
|
282
|
+
performed_jobs_size = performed_jobs_with(only: only, except: except, queue: queue).count
|
283
283
|
end
|
284
284
|
|
285
285
|
assert_equal number, performed_jobs_size, "#{number} jobs expected, but #{performed_jobs_size} were performed"
|
@@ -345,44 +345,40 @@ module ActiveJob
|
|
345
345
|
#
|
346
346
|
# def test_assert_enqueued_with
|
347
347
|
# MyJob.perform_later(1,2,3)
|
348
|
-
# assert_enqueued_with(job: MyJob, args: [1,2,3]
|
348
|
+
# assert_enqueued_with(job: MyJob, args: [1,2,3])
|
349
349
|
#
|
350
|
-
# MyJob.set(wait_until: Date.tomorrow.noon).perform_later
|
351
|
-
# assert_enqueued_with(
|
350
|
+
# MyJob.set(wait_until: Date.tomorrow.noon, queue: "my_queue").perform_later
|
351
|
+
# assert_enqueued_with(at: Date.tomorrow.noon, queue: "my_queue")
|
352
352
|
# end
|
353
353
|
#
|
354
|
-
# The
|
354
|
+
# The given arguments may also be specified as matcher procs that return a
|
355
|
+
# boolean value indicating whether a job's attribute meets certain criteria.
|
355
356
|
#
|
356
|
-
#
|
357
|
+
# For example, a proc can be used to match a range of times:
|
357
358
|
#
|
358
359
|
# def test_assert_enqueued_with
|
359
|
-
#
|
360
|
-
#
|
361
|
-
#
|
360
|
+
# at_matcher = ->(job_at) { (Date.yesterday..Date.tomorrow).cover?(job_at) }
|
361
|
+
#
|
362
|
+
# MyJob.set(wait_until: Date.today.noon).perform_later
|
362
363
|
#
|
363
|
-
# MyJob
|
364
|
-
# assert_enqueued_with(job: MyJob, at: expected_time)
|
364
|
+
# assert_enqueued_with(job: MyJob, at: at_matcher)
|
365
365
|
# end
|
366
366
|
#
|
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.
|
367
|
+
# A proc can also be used to match a subset of a job's args:
|
371
368
|
#
|
372
369
|
# def test_assert_enqueued_with
|
373
|
-
#
|
374
|
-
# assert job_args.first.key?(:foo)
|
375
|
-
# end
|
370
|
+
# args_matcher = ->(job_args) { job_args[0].key?(:foo) }
|
376
371
|
#
|
377
|
-
# MyJob.perform_later(foo:
|
378
|
-
#
|
372
|
+
# MyJob.perform_later(foo: "bar", other_arg: "No need to check in the test")
|
373
|
+
#
|
374
|
+
# assert_enqueued_with(job: MyJob, args: args_matcher)
|
379
375
|
# end
|
380
376
|
#
|
381
377
|
# If a block is passed, asserts that the block will cause the job to be
|
382
378
|
# enqueued with the given arguments.
|
383
379
|
#
|
384
380
|
# def test_assert_enqueued_with
|
385
|
-
# assert_enqueued_with(job: MyJob, args: [1,2,3]
|
381
|
+
# assert_enqueued_with(job: MyJob, args: [1,2,3]) do
|
386
382
|
# MyJob.perform_later(1,2,3)
|
387
383
|
# end
|
388
384
|
#
|
@@ -390,22 +386,24 @@ module ActiveJob
|
|
390
386
|
# MyJob.set(wait_until: Date.tomorrow.noon).perform_later
|
391
387
|
# end
|
392
388
|
# end
|
393
|
-
def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil)
|
389
|
+
def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil, &block)
|
394
390
|
expected = { job: job, args: args, at: at, queue: queue }.compact
|
395
391
|
expected_args = prepare_args_for_assertion(expected)
|
392
|
+
potential_matches = []
|
396
393
|
|
397
394
|
if block_given?
|
398
|
-
|
395
|
+
original_enqueued_jobs = enqueued_jobs.dup
|
399
396
|
|
400
|
-
|
397
|
+
assert_nothing_raised(&block)
|
401
398
|
|
402
|
-
jobs = enqueued_jobs
|
399
|
+
jobs = enqueued_jobs - original_enqueued_jobs
|
403
400
|
else
|
404
401
|
jobs = enqueued_jobs
|
405
402
|
end
|
406
403
|
|
407
404
|
matching_job = jobs.find do |enqueued_job|
|
408
405
|
deserialized_job = deserialize_args_for_assertion(enqueued_job)
|
406
|
+
potential_matches << deserialized_job
|
409
407
|
|
410
408
|
expected_args.all? do |key, value|
|
411
409
|
if value.respond_to?(:call)
|
@@ -416,7 +414,9 @@ module ActiveJob
|
|
416
414
|
end
|
417
415
|
end
|
418
416
|
|
419
|
-
|
417
|
+
message = +"No enqueued job found with #{expected}"
|
418
|
+
message << "\n\nPotential matches: #{potential_matches.join("\n")}" if potential_matches.present?
|
419
|
+
assert matching_job, message
|
420
420
|
instantiate_job(matching_job)
|
421
421
|
end
|
422
422
|
|
@@ -427,42 +427,40 @@ module ActiveJob
|
|
427
427
|
#
|
428
428
|
# perform_enqueued_jobs
|
429
429
|
#
|
430
|
-
# assert_performed_with(job: MyJob, args: [1,2,3]
|
430
|
+
# assert_performed_with(job: MyJob, args: [1,2,3])
|
431
431
|
#
|
432
|
-
# MyJob.set(wait_until: Date.tomorrow.noon).perform_later
|
432
|
+
# MyJob.set(wait_until: Date.tomorrow.noon, queue: "my_queue").perform_later
|
433
433
|
#
|
434
434
|
# perform_enqueued_jobs
|
435
435
|
#
|
436
|
-
# assert_performed_with(
|
436
|
+
# assert_performed_with(at: Date.tomorrow.noon, queue: "my_queue")
|
437
437
|
# end
|
438
438
|
#
|
439
|
-
# The
|
439
|
+
# The given arguments may also be specified as matcher procs that return a
|
440
|
+
# boolean value indicating whether a job's attribute meets certain criteria.
|
440
441
|
#
|
441
|
-
#
|
442
|
+
# For example, a proc can be used to match a range of times:
|
442
443
|
#
|
443
|
-
# def
|
444
|
-
#
|
445
|
-
#
|
446
|
-
#
|
444
|
+
# def test_assert_performed_with
|
445
|
+
# at_matcher = ->(job_at) { (Date.yesterday..Date.tomorrow).cover?(job_at) }
|
446
|
+
#
|
447
|
+
# MyJob.set(wait_until: Date.today.noon).perform_later
|
447
448
|
#
|
448
|
-
#
|
449
|
-
#
|
449
|
+
# perform_enqueued_jobs
|
450
|
+
#
|
451
|
+
# assert_performed_with(job: MyJob, at: at_matcher)
|
450
452
|
# end
|
451
453
|
#
|
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.
|
454
|
+
# A proc can also be used to match a subset of a job's args:
|
456
455
|
#
|
457
456
|
# def test_assert_performed_with
|
458
|
-
#
|
459
|
-
#
|
460
|
-
#
|
461
|
-
# MyJob.perform_later(foo: 'bar', other_arg: 'No need to check in the test')
|
457
|
+
# args_matcher = ->(job_args) { job_args[0].key?(:foo) }
|
458
|
+
#
|
459
|
+
# MyJob.perform_later(foo: "bar", other_arg: "No need to check in the test")
|
462
460
|
#
|
463
461
|
# perform_enqueued_jobs
|
464
462
|
#
|
465
|
-
# assert_performed_with(job: MyJob, args:
|
463
|
+
# assert_performed_with(job: MyJob, args: args_matcher)
|
466
464
|
# end
|
467
465
|
#
|
468
466
|
# If a block is passed, that block performs all of the jobs that were
|
@@ -470,7 +468,7 @@ module ActiveJob
|
|
470
468
|
# the job has been performed with the given arguments in the block.
|
471
469
|
#
|
472
470
|
# def test_assert_performed_with
|
473
|
-
# assert_performed_with(job: MyJob, args: [1,2,3]
|
471
|
+
# assert_performed_with(job: MyJob, args: [1,2,3]) do
|
474
472
|
# MyJob.perform_later(1,2,3)
|
475
473
|
# end
|
476
474
|
#
|
@@ -481,6 +479,7 @@ module ActiveJob
|
|
481
479
|
def assert_performed_with(job: nil, args: nil, at: nil, queue: nil, &block)
|
482
480
|
expected = { job: job, args: args, at: at, queue: queue }.compact
|
483
481
|
expected_args = prepare_args_for_assertion(expected)
|
482
|
+
potential_matches = []
|
484
483
|
|
485
484
|
if block_given?
|
486
485
|
original_performed_jobs_count = performed_jobs.count
|
@@ -494,6 +493,7 @@ module ActiveJob
|
|
494
493
|
|
495
494
|
matching_job = jobs.find do |enqueued_job|
|
496
495
|
deserialized_job = deserialize_args_for_assertion(enqueued_job)
|
496
|
+
potential_matches << deserialized_job
|
497
497
|
|
498
498
|
expected_args.all? do |key, value|
|
499
499
|
if value.respond_to?(:call)
|
@@ -504,7 +504,10 @@ module ActiveJob
|
|
504
504
|
end
|
505
505
|
end
|
506
506
|
|
507
|
-
|
507
|
+
message = +"No performed job found with #{expected}"
|
508
|
+
message << "\n\nPotential matches: #{potential_matches.join("\n")}" if potential_matches.present?
|
509
|
+
assert matching_job, message
|
510
|
+
|
508
511
|
instantiate_job(matching_job)
|
509
512
|
end
|
510
513
|
|
@@ -563,8 +566,10 @@ module ActiveJob
|
|
563
566
|
# assert_performed_jobs 1
|
564
567
|
# end
|
565
568
|
#
|
566
|
-
|
567
|
-
|
569
|
+
# If the +:at+ option is specified, then only run jobs enqueued to run
|
570
|
+
# immediately or before the given time
|
571
|
+
def perform_enqueued_jobs(only: nil, except: nil, queue: nil, at: nil, &block)
|
572
|
+
return flush_enqueued_jobs(only: only, except: except, queue: queue, at: at) unless block_given?
|
568
573
|
|
569
574
|
validate_option(only: only, except: except)
|
570
575
|
|
@@ -573,6 +578,7 @@ module ActiveJob
|
|
573
578
|
old_filter = queue_adapter.filter
|
574
579
|
old_reject = queue_adapter.reject
|
575
580
|
old_queue = queue_adapter.queue
|
581
|
+
old_at = queue_adapter.at
|
576
582
|
|
577
583
|
begin
|
578
584
|
queue_adapter.perform_enqueued_jobs = true
|
@@ -580,14 +586,16 @@ module ActiveJob
|
|
580
586
|
queue_adapter.filter = only
|
581
587
|
queue_adapter.reject = except
|
582
588
|
queue_adapter.queue = queue
|
589
|
+
queue_adapter.at = at
|
583
590
|
|
584
|
-
|
591
|
+
assert_nothing_raised(&block)
|
585
592
|
ensure
|
586
593
|
queue_adapter.perform_enqueued_jobs = old_perform_enqueued_jobs
|
587
594
|
queue_adapter.perform_enqueued_at_jobs = old_perform_enqueued_at_jobs
|
588
595
|
queue_adapter.filter = old_filter
|
589
596
|
queue_adapter.reject = old_reject
|
590
597
|
queue_adapter.queue = old_queue
|
598
|
+
queue_adapter.at = old_at
|
591
599
|
end
|
592
600
|
end
|
593
601
|
|
@@ -609,10 +617,10 @@ module ActiveJob
|
|
609
617
|
performed_jobs.clear
|
610
618
|
end
|
611
619
|
|
612
|
-
def jobs_with(jobs, only: nil, except: nil, queue: nil)
|
620
|
+
def jobs_with(jobs, only: nil, except: nil, queue: nil, at: nil)
|
613
621
|
validate_option(only: only, except: except)
|
614
622
|
|
615
|
-
jobs.
|
623
|
+
jobs.dup.select do |job|
|
616
624
|
job_class = job.fetch(:job)
|
617
625
|
|
618
626
|
if only
|
@@ -625,6 +633,10 @@ module ActiveJob
|
|
625
633
|
next false unless queue.to_s == job.fetch(:queue, job_class.queue_name)
|
626
634
|
end
|
627
635
|
|
636
|
+
if at && job[:at]
|
637
|
+
next false if job[:at] > at.to_f
|
638
|
+
end
|
639
|
+
|
628
640
|
yield job if block_given?
|
629
641
|
|
630
642
|
true
|
@@ -637,41 +649,28 @@ module ActiveJob
|
|
637
649
|
->(job) { Array(filter).include?(job.fetch(:job)) }
|
638
650
|
end
|
639
651
|
|
640
|
-
def enqueued_jobs_with(only: nil, except: nil, queue: nil, &block)
|
641
|
-
jobs_with(enqueued_jobs, only: only, except: except, queue: queue, &block)
|
652
|
+
def enqueued_jobs_with(only: nil, except: nil, queue: nil, at: nil, &block)
|
653
|
+
jobs_with(enqueued_jobs, only: only, except: except, queue: queue, at: at, &block)
|
642
654
|
end
|
643
655
|
|
644
656
|
def performed_jobs_with(only: nil, except: nil, queue: nil, &block)
|
645
657
|
jobs_with(performed_jobs, only: only, except: except, queue: queue, &block)
|
646
658
|
end
|
647
659
|
|
648
|
-
def flush_enqueued_jobs(only: nil, except: nil, queue: nil)
|
649
|
-
enqueued_jobs_with(only: only, except: except, queue: queue) do |payload|
|
650
|
-
|
660
|
+
def flush_enqueued_jobs(only: nil, except: nil, queue: nil, at: nil)
|
661
|
+
enqueued_jobs_with(only: only, except: except, queue: queue, at: at) do |payload|
|
662
|
+
queue_adapter.enqueued_jobs.delete(payload)
|
651
663
|
queue_adapter.performed_jobs << payload
|
652
|
-
|
664
|
+
instantiate_job(payload).perform_now
|
665
|
+
end.count
|
653
666
|
end
|
654
667
|
|
655
668
|
def prepare_args_for_assertion(args)
|
656
669
|
args.dup.tap do |arguments|
|
657
|
-
if arguments[:at]
|
670
|
+
if arguments[:at].acts_like?(:time)
|
658
671
|
at_range = arguments[:at] - 1..arguments[:at] + 1
|
659
672
|
arguments[:at] = ->(at) { at_range.cover?(at) }
|
660
673
|
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
674
|
end
|
676
675
|
end
|
677
676
|
|