activejob 6.0.6.1 → 6.1.0.rc1
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 +74 -237
- data/MIT-LICENSE +1 -1
- data/README.md +2 -4
- data/lib/active_job/base.rb +3 -0
- data/lib/active_job/callbacks.rb +44 -4
- data/lib/active_job/core.rb +2 -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/inline_adapter.rb +1 -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_adapters.rb +5 -1
- data/lib/active_job/queue_name.rb +2 -2
- data/lib/active_job/railtie.rb +4 -0
- 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/serializers.rb +4 -1
- data/lib/active_job/test_helper.rb +79 -80
- data/lib/active_job.rb +1 -1
- metadata +17 -14
@@ -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
|
|
data/lib/active_job.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c) 2014-
|
4
|
+
# Copyright (c) 2014-2020 David Heinemeier Hansson
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
7
7
|
# a copy of this software and associated documentation files (the
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activejob
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.0.
|
4
|
+
version: 6.1.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 6.0.
|
19
|
+
version: 6.1.0.rc1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 6.0.
|
26
|
+
version: 6.1.0.rc1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: globalid
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -57,6 +57,8 @@ files:
|
|
57
57
|
- lib/active_job/exceptions.rb
|
58
58
|
- lib/active_job/execution.rb
|
59
59
|
- lib/active_job/gem_version.rb
|
60
|
+
- lib/active_job/instrumentation.rb
|
61
|
+
- lib/active_job/log_subscriber.rb
|
60
62
|
- lib/active_job/logging.rb
|
61
63
|
- lib/active_job/queue_adapter.rb
|
62
64
|
- lib/active_job/queue_adapters.rb
|
@@ -78,8 +80,10 @@ files:
|
|
78
80
|
- lib/active_job/serializers/date_serializer.rb
|
79
81
|
- lib/active_job/serializers/date_time_serializer.rb
|
80
82
|
- lib/active_job/serializers/duration_serializer.rb
|
83
|
+
- lib/active_job/serializers/module_serializer.rb
|
81
84
|
- lib/active_job/serializers/object_serializer.rb
|
82
85
|
- lib/active_job/serializers/symbol_serializer.rb
|
86
|
+
- lib/active_job/serializers/time_object_serializer.rb
|
83
87
|
- lib/active_job/serializers/time_serializer.rb
|
84
88
|
- lib/active_job/serializers/time_with_zone_serializer.rb
|
85
89
|
- lib/active_job/test_case.rb
|
@@ -95,12 +99,11 @@ licenses:
|
|
95
99
|
- MIT
|
96
100
|
metadata:
|
97
101
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
98
|
-
changelog_uri: https://github.com/rails/rails/blob/v6.0.
|
99
|
-
documentation_uri: https://api.rubyonrails.org/v6.0.
|
102
|
+
changelog_uri: https://github.com/rails/rails/blob/v6.1.0.rc1/activejob/CHANGELOG.md
|
103
|
+
documentation_uri: https://api.rubyonrails.org/v6.1.0.rc1/
|
100
104
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
101
|
-
source_code_uri: https://github.com/rails/rails/tree/v6.0.
|
102
|
-
|
103
|
-
post_install_message:
|
105
|
+
source_code_uri: https://github.com/rails/rails/tree/v6.1.0.rc1/activejob
|
106
|
+
post_install_message:
|
104
107
|
rdoc_options: []
|
105
108
|
require_paths:
|
106
109
|
- lib
|
@@ -111,12 +114,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
111
114
|
version: 2.5.0
|
112
115
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
116
|
requirements:
|
114
|
-
- - "
|
117
|
+
- - ">"
|
115
118
|
- !ruby/object:Gem::Version
|
116
|
-
version:
|
119
|
+
version: 1.3.1
|
117
120
|
requirements: []
|
118
|
-
rubygems_version: 3.4
|
119
|
-
signing_key:
|
121
|
+
rubygems_version: 3.1.4
|
122
|
+
signing_key:
|
120
123
|
specification_version: 4
|
121
124
|
summary: Job framework with pluggable queues.
|
122
125
|
test_files: []
|