activejob 6.0.6.1 → 6.1.0.rc1
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 -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: []
|