activejob 7.0.8 → 7.2.0
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 +35 -214
- data/MIT-LICENSE +1 -1
- data/README.md +2 -2
- data/lib/active_job/arguments.rb +18 -32
- data/lib/active_job/base.rb +1 -1
- data/lib/active_job/callbacks.rb +3 -8
- data/lib/active_job/configured_job.rb +4 -0
- data/lib/active_job/core.rb +11 -6
- data/lib/active_job/deprecator.rb +7 -0
- data/lib/active_job/enqueue_after_transaction_commit.rb +28 -0
- data/lib/active_job/enqueuing.rb +71 -12
- data/lib/active_job/exceptions.rb +44 -7
- data/lib/active_job/execution.rb +5 -2
- data/lib/active_job/gem_version.rb +3 -3
- data/lib/active_job/instrumentation.rb +18 -10
- data/lib/active_job/log_subscriber.rb +80 -8
- data/lib/active_job/logging.rb +16 -2
- data/lib/active_job/queue_adapter.rb +18 -6
- data/lib/active_job/queue_adapters/abstract_adapter.rb +27 -0
- data/lib/active_job/queue_adapters/async_adapter.rb +3 -3
- data/lib/active_job/queue_adapters/backburner_adapter.rb +8 -4
- data/lib/active_job/queue_adapters/delayed_job_adapter.rb +10 -2
- data/lib/active_job/queue_adapters/inline_adapter.rb +6 -2
- data/lib/active_job/queue_adapters/queue_classic_adapter.rb +13 -5
- data/lib/active_job/queue_adapters/resque_adapter.rb +2 -2
- data/lib/active_job/queue_adapters/sidekiq_adapter.rb +43 -15
- data/lib/active_job/queue_adapters/sneakers_adapter.rb +2 -2
- data/lib/active_job/queue_adapters/sucker_punch_adapter.rb +4 -4
- data/lib/active_job/queue_adapters/test_adapter.rb +13 -5
- data/lib/active_job/queue_adapters.rb +9 -7
- data/lib/active_job/queue_priority.rb +18 -1
- data/lib/active_job/railtie.rb +38 -7
- data/lib/active_job/serializers/big_decimal_serializer.rb +22 -0
- data/lib/active_job/serializers/duration_serializer.rb +4 -2
- data/lib/active_job/serializers/object_serializer.rb +2 -0
- data/lib/active_job/serializers/time_with_zone_serializer.rb +11 -2
- data/lib/active_job/serializers.rb +7 -3
- data/lib/active_job/test_helper.rb +60 -19
- data/lib/active_job/version.rb +1 -1
- data/lib/active_job.rb +34 -4
- data/lib/rails/generators/job/USAGE +19 -0
- data/lib/rails/generators/job/job_generator.rb +6 -2
- data/lib/rails/generators/job/templates/job.rb.tt +1 -1
- metadata +14 -10
- data/lib/active_job/queue_adapters/que_adapter.rb +0 -61
@@ -1,14 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
gem "sidekiq", ">= 4.1.0"
|
3
4
|
require "sidekiq"
|
4
5
|
|
5
6
|
module ActiveJob
|
6
7
|
module QueueAdapters
|
7
|
-
#
|
8
|
+
# = Sidekiq adapter for Active Job
|
8
9
|
#
|
9
10
|
# Simple, efficient background processing for Ruby. Sidekiq uses threads to
|
10
11
|
# handle many jobs at the same time in the same process. It does not
|
11
|
-
# require Rails but will integrate tightly with it to make background
|
12
|
+
# require \Rails but will integrate tightly with it to make background
|
12
13
|
# processing dead simple.
|
13
14
|
#
|
14
15
|
# Read more about Sidekiq {here}[http://sidekiq.org].
|
@@ -16,23 +17,50 @@ module ActiveJob
|
|
16
17
|
# To use Sidekiq set the queue_adapter config to +:sidekiq+.
|
17
18
|
#
|
18
19
|
# Rails.application.config.active_job.queue_adapter = :sidekiq
|
19
|
-
class SidekiqAdapter
|
20
|
+
class SidekiqAdapter < AbstractAdapter
|
20
21
|
def enqueue(job) # :nodoc:
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
"queue" => job.queue_name,
|
26
|
-
"args" => [ job.serialize ]
|
22
|
+
job.provider_job_id = JobWrapper.set(
|
23
|
+
wrapped: job.class,
|
24
|
+
queue: job.queue_name
|
25
|
+
).perform_async(job.serialize)
|
27
26
|
end
|
28
27
|
|
29
28
|
def enqueue_at(job, timestamp) # :nodoc:
|
30
|
-
job.provider_job_id =
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
29
|
+
job.provider_job_id = JobWrapper.set(
|
30
|
+
wrapped: job.class,
|
31
|
+
queue: job.queue_name,
|
32
|
+
).perform_at(timestamp, job.serialize)
|
33
|
+
end
|
34
|
+
|
35
|
+
def enqueue_all(jobs) # :nodoc:
|
36
|
+
enqueued_count = 0
|
37
|
+
jobs.group_by(&:class).each do |job_class, same_class_jobs|
|
38
|
+
same_class_jobs.group_by(&:queue_name).each do |queue, same_class_and_queue_jobs|
|
39
|
+
immediate_jobs, scheduled_jobs = same_class_and_queue_jobs.partition { |job| job.scheduled_at.nil? }
|
40
|
+
|
41
|
+
if immediate_jobs.any?
|
42
|
+
jids = Sidekiq::Client.push_bulk(
|
43
|
+
"class" => JobWrapper,
|
44
|
+
"wrapped" => job_class,
|
45
|
+
"queue" => queue,
|
46
|
+
"args" => immediate_jobs.map { |job| [job.serialize] },
|
47
|
+
)
|
48
|
+
enqueued_count += jids.compact.size
|
49
|
+
end
|
50
|
+
|
51
|
+
if scheduled_jobs.any?
|
52
|
+
jids = Sidekiq::Client.push_bulk(
|
53
|
+
"class" => JobWrapper,
|
54
|
+
"wrapped" => job_class,
|
55
|
+
"queue" => queue,
|
56
|
+
"args" => scheduled_jobs.map { |job| [job.serialize] },
|
57
|
+
"at" => scheduled_jobs.map { |job| job.scheduled_at&.to_f }
|
58
|
+
)
|
59
|
+
enqueued_count += jids.compact.size
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
enqueued_count
|
36
64
|
end
|
37
65
|
|
38
66
|
class JobWrapper # :nodoc:
|
@@ -5,7 +5,7 @@ require "monitor"
|
|
5
5
|
|
6
6
|
module ActiveJob
|
7
7
|
module QueueAdapters
|
8
|
-
#
|
8
|
+
# = Sneakers adapter for Active Job
|
9
9
|
#
|
10
10
|
# A high-performance RabbitMQ background processing framework for Ruby.
|
11
11
|
# Sneakers is being used in production for both I/O and CPU intensive
|
@@ -17,7 +17,7 @@ module ActiveJob
|
|
17
17
|
# To use Sneakers set the queue_adapter config to +:sneakers+.
|
18
18
|
#
|
19
19
|
# Rails.application.config.active_job.queue_adapter = :sneakers
|
20
|
-
class SneakersAdapter
|
20
|
+
class SneakersAdapter < AbstractAdapter
|
21
21
|
def initialize
|
22
22
|
@monitor = Monitor.new
|
23
23
|
end
|
@@ -4,20 +4,20 @@ require "sucker_punch"
|
|
4
4
|
|
5
5
|
module ActiveJob
|
6
6
|
module QueueAdapters
|
7
|
-
#
|
7
|
+
# = Sucker Punch adapter for Active Job
|
8
8
|
#
|
9
9
|
# Sucker Punch is a single-process Ruby asynchronous processing library.
|
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 (e.g. Rails, Sinatra, etc.) process.
|
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
|
#
|
17
17
|
# To use Sucker Punch set the queue_adapter config to +:sucker_punch+.
|
18
18
|
#
|
19
19
|
# Rails.application.config.active_job.queue_adapter = :sucker_punch
|
20
|
-
class SuckerPunchAdapter
|
20
|
+
class SuckerPunchAdapter < AbstractAdapter
|
21
21
|
def enqueue(job) # :nodoc:
|
22
22
|
if JobWrapper.respond_to?(:perform_async)
|
23
23
|
# sucker_punch 2.0 API
|
@@ -33,7 +33,7 @@ module ActiveJob
|
|
33
33
|
delay = timestamp - Time.current.to_f
|
34
34
|
JobWrapper.perform_in delay, job.serialize
|
35
35
|
else
|
36
|
-
raise NotImplementedError, "sucker_punch 1.0 does not support `
|
36
|
+
raise NotImplementedError, "sucker_punch 1.0 does not support `enqueue_at`. Please upgrade to version ~> 2.0.0 to enable this behavior."
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -2,19 +2,27 @@
|
|
2
2
|
|
3
3
|
module ActiveJob
|
4
4
|
module QueueAdapters
|
5
|
-
#
|
5
|
+
# = Test adapter for Active Job
|
6
6
|
#
|
7
7
|
# The test adapter should be used only in testing. Along with
|
8
8
|
# ActiveJob::TestCase and ActiveJob::TestHelper
|
9
|
-
# it makes a great tool to test your Rails application.
|
9
|
+
# it makes a great tool to test your \Rails application.
|
10
10
|
#
|
11
11
|
# To use the test adapter set +queue_adapter+ config to +:test+.
|
12
12
|
#
|
13
13
|
# Rails.application.config.active_job.queue_adapter = :test
|
14
|
-
class TestAdapter
|
15
|
-
attr_accessor(:perform_enqueued_jobs, :perform_enqueued_at_jobs, :filter, :reject, :queue, :at)
|
14
|
+
class TestAdapter < AbstractAdapter
|
15
|
+
attr_accessor(:perform_enqueued_jobs, :perform_enqueued_at_jobs, :filter, :reject, :queue, :at, :enqueue_after_transaction_commit)
|
16
16
|
attr_writer(:enqueued_jobs, :performed_jobs)
|
17
17
|
|
18
|
+
def initialize(enqueue_after_transaction_commit: true)
|
19
|
+
@enqueue_after_transaction_commit = enqueue_after_transaction_commit
|
20
|
+
end
|
21
|
+
|
22
|
+
def enqueue_after_transaction_commit? # :nodoc:
|
23
|
+
@enqueue_after_transaction_commit
|
24
|
+
end
|
25
|
+
|
18
26
|
# Provides a store of all the enqueued jobs with the TestAdapter so you can check them.
|
19
27
|
def enqueued_jobs
|
20
28
|
@enqueued_jobs ||= []
|
@@ -59,7 +67,7 @@ module ActiveJob
|
|
59
67
|
end
|
60
68
|
|
61
69
|
def filtered_time?(job)
|
62
|
-
job.scheduled_at > at
|
70
|
+
job.scheduled_at > at if at && job.scheduled_at
|
63
71
|
end
|
64
72
|
|
65
73
|
def filtered_queue?(job)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveJob
|
4
|
-
#
|
4
|
+
# = Active Job adapters
|
5
5
|
#
|
6
6
|
# Active Job has adapters for the following queuing backends:
|
7
7
|
#
|
@@ -13,10 +13,14 @@ module ActiveJob
|
|
13
13
|
# * {Sidekiq}[https://sidekiq.org]
|
14
14
|
# * {Sneakers}[https://github.com/jondot/sneakers]
|
15
15
|
# * {Sucker Punch}[https://github.com/brandonhilkert/sucker_punch]
|
16
|
-
# * {Active Job Async Job}[https://api.rubyonrails.org/classes/ActiveJob/QueueAdapters/AsyncAdapter.html]
|
17
|
-
# * {Active Job Inline}[https://api.rubyonrails.org/classes/ActiveJob/QueueAdapters/InlineAdapter.html]
|
18
16
|
# * Please Note: We are not accepting pull requests for new adapters. See the {README}[link:files/activejob/README_md.html] for more details.
|
19
17
|
#
|
18
|
+
# For testing and development Active Job has three built-in adapters:
|
19
|
+
#
|
20
|
+
# * {Active Job Async}[https://api.rubyonrails.org/classes/ActiveJob/QueueAdapters/AsyncAdapter.html]
|
21
|
+
# * {Active Job Inline}[https://api.rubyonrails.org/classes/ActiveJob/QueueAdapters/InlineAdapter.html]
|
22
|
+
# * {Active Job Test}[https://api.rubyonrails.org/classes/ActiveJob/QueueAdapters/TestAdapter.html]
|
23
|
+
#
|
20
24
|
# === Backends Features
|
21
25
|
#
|
22
26
|
# | | Async | Queues | Delayed | Priorities | Timeout | Retries |
|
@@ -31,6 +35,7 @@ module ActiveJob
|
|
31
35
|
# | Sucker Punch | Yes | Yes | Yes | No | No | No |
|
32
36
|
# | Active Job Async | Yes | Yes | Yes | No | No | No |
|
33
37
|
# | Active Job Inline | No | Yes | N/A | N/A | N/A | N/A |
|
38
|
+
# | Active Job Test | No | Yes | N/A | N/A | N/A | N/A |
|
34
39
|
#
|
35
40
|
# ==== Async
|
36
41
|
#
|
@@ -106,13 +111,10 @@ module ActiveJob
|
|
106
111
|
# N/A: The adapter does not run in a separate process, and therefore doesn't
|
107
112
|
# support retries.
|
108
113
|
#
|
109
|
-
# === Async and Inline Queue Adapters
|
110
|
-
#
|
111
|
-
# Active Job has two built-in queue adapters intended for development and
|
112
|
-
# testing: +:async+ and +:inline+.
|
113
114
|
module QueueAdapters
|
114
115
|
extend ActiveSupport::Autoload
|
115
116
|
|
117
|
+
autoload :AbstractAdapter
|
116
118
|
autoload :AsyncAdapter
|
117
119
|
autoload :InlineAdapter
|
118
120
|
autoload :BackburnerAdapter
|
@@ -18,7 +18,24 @@ module ActiveJob
|
|
18
18
|
# end
|
19
19
|
# end
|
20
20
|
#
|
21
|
-
#
|
21
|
+
# Can be given a block that will evaluate in the context of the job
|
22
|
+
# so that a dynamic priority can be applied:
|
23
|
+
#
|
24
|
+
# class PublishToFeedJob < ApplicationJob
|
25
|
+
# queue_with_priority do
|
26
|
+
# post = self.arguments.first
|
27
|
+
#
|
28
|
+
# if post.paid?
|
29
|
+
# 10
|
30
|
+
# else
|
31
|
+
# 50
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# def perform(post)
|
36
|
+
# post.to_feed!
|
37
|
+
# end
|
38
|
+
# end
|
22
39
|
def queue_with_priority(priority = nil, &block)
|
23
40
|
if block_given?
|
24
41
|
self.priority = block
|
data/lib/active_job/railtie.rb
CHANGED
@@ -10,6 +10,10 @@ module ActiveJob
|
|
10
10
|
config.active_job.custom_serializers = []
|
11
11
|
config.active_job.log_query_tags_around_perform = true
|
12
12
|
|
13
|
+
initializer "active_job.deprecator", before: :load_environment_config do |app|
|
14
|
+
app.deprecators[:active_job] = ActiveJob.deprecator
|
15
|
+
end
|
16
|
+
|
13
17
|
initializer "active_job.logger" do
|
14
18
|
ActiveSupport.on_load(:active_job) { self.logger = ::Rails.logger }
|
15
19
|
end
|
@@ -21,9 +25,30 @@ module ActiveJob
|
|
21
25
|
end
|
22
26
|
end
|
23
27
|
|
28
|
+
initializer "active_job.enqueue_after_transaction_commit" do |app|
|
29
|
+
ActiveSupport.on_load(:active_job) do
|
30
|
+
ActiveSupport.on_load(:active_record) do
|
31
|
+
ActiveJob::Base.include EnqueueAfterTransactionCommit
|
32
|
+
|
33
|
+
if app.config.active_job.key?(:enqueue_after_transaction_commit)
|
34
|
+
ActiveJob::Base.enqueue_after_transaction_commit = app.config.active_job.delete(:enqueue_after_transaction_commit)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
24
40
|
initializer "active_job.set_configs" do |app|
|
25
41
|
options = app.config.active_job
|
26
|
-
options.queue_adapter ||= :async
|
42
|
+
options.queue_adapter ||= (Rails.env.test? ? :test : :async)
|
43
|
+
|
44
|
+
config.after_initialize do
|
45
|
+
options.each do |k, v|
|
46
|
+
k = "#{k}="
|
47
|
+
if ActiveJob.respond_to?(k)
|
48
|
+
ActiveJob.send(k, v)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
27
52
|
|
28
53
|
ActiveSupport.on_load(:active_job) do
|
29
54
|
# Configs used in other initializers
|
@@ -32,19 +57,19 @@ module ActiveJob
|
|
32
57
|
:custom_serializers
|
33
58
|
)
|
34
59
|
|
35
|
-
options.each do
|
60
|
+
options.each do |k, v|
|
36
61
|
k = "#{k}="
|
37
|
-
|
62
|
+
if ActiveJob.respond_to?(k)
|
63
|
+
ActiveJob.send(k, v)
|
64
|
+
elsif respond_to? k
|
65
|
+
send(k, v)
|
66
|
+
end
|
38
67
|
end
|
39
68
|
end
|
40
69
|
|
41
70
|
ActiveSupport.on_load(:action_dispatch_integration_test) do
|
42
71
|
include ActiveJob::TestHelper
|
43
72
|
end
|
44
|
-
|
45
|
-
ActiveSupport.on_load(:active_record) do
|
46
|
-
self.destroy_association_async_job = ActiveRecord::DestroyAssociationAsyncJob
|
47
|
-
end
|
48
73
|
end
|
49
74
|
|
50
75
|
initializer "active_job.set_reloader_hook" do |app|
|
@@ -70,5 +95,11 @@ module ActiveJob
|
|
70
95
|
end
|
71
96
|
end
|
72
97
|
end
|
98
|
+
|
99
|
+
initializer "active_job.backtrace_cleaner" do
|
100
|
+
ActiveSupport.on_load(:active_job) do
|
101
|
+
LogSubscriber.backtrace_cleaner = ::Rails.backtrace_cleaner
|
102
|
+
end
|
103
|
+
end
|
73
104
|
end
|
74
105
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bigdecimal"
|
4
|
+
|
5
|
+
module ActiveJob
|
6
|
+
module Serializers
|
7
|
+
class BigDecimalSerializer < ObjectSerializer # :nodoc:
|
8
|
+
def serialize(big_decimal)
|
9
|
+
super("value" => big_decimal.to_s)
|
10
|
+
end
|
11
|
+
|
12
|
+
def deserialize(hash)
|
13
|
+
BigDecimal(hash["value"])
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def klass
|
18
|
+
BigDecimal
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -4,14 +4,16 @@ module ActiveJob
|
|
4
4
|
module Serializers
|
5
5
|
class DurationSerializer < ObjectSerializer # :nodoc:
|
6
6
|
def serialize(duration)
|
7
|
+
# Ideally duration.parts would be wrapped in an array before passing to Arguments.serialize,
|
8
|
+
# but we continue passing the bare hash for backwards compatibility:
|
7
9
|
super("value" => duration.value, "parts" => Arguments.serialize(duration.parts))
|
8
10
|
end
|
9
11
|
|
10
12
|
def deserialize(hash)
|
11
13
|
value = hash["value"]
|
12
14
|
parts = Arguments.deserialize(hash["parts"])
|
13
|
-
|
14
|
-
klass.new(value, parts)
|
15
|
+
# `parts` is originally a hash, but will have been flattened to an array by Arguments.serialize
|
16
|
+
klass.new(value, parts.to_h)
|
15
17
|
end
|
16
18
|
|
17
19
|
private
|
@@ -2,9 +2,18 @@
|
|
2
2
|
|
3
3
|
module ActiveJob
|
4
4
|
module Serializers
|
5
|
-
class TimeWithZoneSerializer <
|
5
|
+
class TimeWithZoneSerializer < ObjectSerializer # :nodoc:
|
6
|
+
NANO_PRECISION = 9
|
7
|
+
|
8
|
+
def serialize(time_with_zone)
|
9
|
+
super(
|
10
|
+
"value" => time_with_zone.iso8601(NANO_PRECISION),
|
11
|
+
"time_zone" => time_with_zone.time_zone.tzinfo.name
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
6
15
|
def deserialize(hash)
|
7
|
-
Time.iso8601(hash["value"]).in_time_zone
|
16
|
+
Time.iso8601(hash["value"]).in_time_zone(hash["time_zone"] || Time.zone)
|
8
17
|
end
|
9
18
|
|
10
19
|
private
|
@@ -3,7 +3,9 @@
|
|
3
3
|
require "set"
|
4
4
|
|
5
5
|
module ActiveJob
|
6
|
-
#
|
6
|
+
# = Active Job \Serializers
|
7
|
+
#
|
8
|
+
# The +ActiveJob::Serializers+ module is used to store a list of known serializers
|
7
9
|
# and to add new ones. It also has helpers to serialize/deserialize objects.
|
8
10
|
module Serializers # :nodoc:
|
9
11
|
extend ActiveSupport::Autoload
|
@@ -18,6 +20,7 @@ module ActiveJob
|
|
18
20
|
autoload :TimeSerializer
|
19
21
|
autoload :ModuleSerializer
|
20
22
|
autoload :RangeSerializer
|
23
|
+
autoload :BigDecimalSerializer
|
21
24
|
|
22
25
|
mattr_accessor :_additional_serializers
|
23
26
|
self._additional_serializers = Set.new
|
@@ -25,7 +28,7 @@ module ActiveJob
|
|
25
28
|
class << self
|
26
29
|
# Returns serialized representative of the passed object.
|
27
30
|
# Will look up through all known serializers.
|
28
|
-
# Raises
|
31
|
+
# Raises ActiveJob::SerializationError if it can't find a proper serializer.
|
29
32
|
def serialize(argument)
|
30
33
|
serializer = serializers.detect { |s| s.serialize?(argument) }
|
31
34
|
raise SerializationError.new("Unsupported argument type: #{argument.class.name}") unless serializer
|
@@ -63,6 +66,7 @@ module ActiveJob
|
|
63
66
|
TimeWithZoneSerializer,
|
64
67
|
TimeSerializer,
|
65
68
|
ModuleSerializer,
|
66
|
-
RangeSerializer
|
69
|
+
RangeSerializer,
|
70
|
+
BigDecimalSerializer
|
67
71
|
end
|
68
72
|
end
|
@@ -34,13 +34,18 @@ module ActiveJob
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
|
37
|
+
ActiveSupport.on_load(:active_job) do
|
38
|
+
ActiveJob::Base.include(TestQueueAdapter)
|
39
|
+
end
|
38
40
|
|
39
41
|
def before_setup # :nodoc:
|
40
|
-
|
41
|
-
|
42
|
+
queue_adapter_specific_to_this_test_class = queue_adapter_for_test
|
42
43
|
queue_adapter_changed_jobs.each do |klass|
|
43
|
-
|
44
|
+
if queue_adapter_specific_to_this_test_class
|
45
|
+
klass.enable_test_adapter(queue_adapter_specific_to_this_test_class)
|
46
|
+
elsif klass._queue_adapter.nil?
|
47
|
+
klass.enable_test_adapter(ActiveJob::QueueAdapters::TestAdapter.new)
|
48
|
+
end
|
44
49
|
end
|
45
50
|
|
46
51
|
clear_enqueued_jobs
|
@@ -54,17 +59,11 @@ module ActiveJob
|
|
54
59
|
queue_adapter_changed_jobs.each { |klass| klass.disable_test_adapter }
|
55
60
|
end
|
56
61
|
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
# ActiveJob::QueueAdapters::TestAdapter.
|
61
|
-
#
|
62
|
-
# Note: The adapter provided by this method must provide some additional
|
63
|
-
# methods from those expected of a standard ActiveJob::QueueAdapter
|
64
|
-
# in order to be used with the active job test helpers. Refer to
|
65
|
-
# ActiveJob::QueueAdapters::TestAdapter.
|
62
|
+
# Returns a queue adapter instance to use with all Active Job test helpers.
|
63
|
+
# By default, returns an instance of ActiveJob::QueueAdapters::TestAdapter.
|
64
|
+
# Override this method to specify a different adapter. The adapter must
|
65
|
+
# implement the same interface as ActiveJob::QueueAdapters::TestAdapter.
|
66
66
|
def queue_adapter_for_test
|
67
|
-
ActiveJob::QueueAdapters::TestAdapter.new
|
68
67
|
end
|
69
68
|
|
70
69
|
# Asserts that the number of enqueued jobs matches the given number.
|
@@ -121,6 +120,8 @@ module ActiveJob
|
|
121
120
|
# end
|
122
121
|
# end
|
123
122
|
def assert_enqueued_jobs(number, only: nil, except: nil, queue: nil, &block)
|
123
|
+
require_active_job_test_adapter!("assert_enqueued_jobs")
|
124
|
+
|
124
125
|
if block_given?
|
125
126
|
original_jobs = enqueued_jobs_with(only: only, except: except, queue: queue)
|
126
127
|
|
@@ -183,6 +184,8 @@ module ActiveJob
|
|
183
184
|
#
|
184
185
|
# assert_enqueued_jobs 0, &block
|
185
186
|
def assert_no_enqueued_jobs(only: nil, except: nil, queue: nil, &block)
|
187
|
+
require_active_job_test_adapter!("assert_no_enqueued_jobs")
|
188
|
+
|
186
189
|
assert_enqueued_jobs 0, only: only, except: except, queue: queue, &block
|
187
190
|
end
|
188
191
|
|
@@ -273,6 +276,8 @@ module ActiveJob
|
|
273
276
|
# end
|
274
277
|
# end
|
275
278
|
def assert_performed_jobs(number, only: nil, except: nil, queue: nil, &block)
|
279
|
+
require_active_job_test_adapter!("assert_performed_jobs")
|
280
|
+
|
276
281
|
if block_given?
|
277
282
|
original_count = performed_jobs.size
|
278
283
|
|
@@ -341,6 +346,8 @@ module ActiveJob
|
|
341
346
|
#
|
342
347
|
# assert_performed_jobs 0, &block
|
343
348
|
def assert_no_performed_jobs(only: nil, except: nil, queue: nil, &block)
|
349
|
+
require_active_job_test_adapter!("assert_no_performed_jobs")
|
350
|
+
|
344
351
|
assert_performed_jobs 0, only: only, except: except, queue: queue, &block
|
345
352
|
end
|
346
353
|
|
@@ -354,6 +361,13 @@ module ActiveJob
|
|
354
361
|
# assert_enqueued_with(at: Date.tomorrow.noon, queue: "my_queue")
|
355
362
|
# end
|
356
363
|
#
|
364
|
+
# For keyword arguments, specify them as a hash inside an array:
|
365
|
+
#
|
366
|
+
# def test_assert_enqueued_with_keyword_arguments
|
367
|
+
# MyJob.perform_later(arg1: 'value1', arg2: 'value2')
|
368
|
+
# assert_enqueued_with(job: MyJob, args: [{ arg1: 'value1', arg2: 'value2' }])
|
369
|
+
# end
|
370
|
+
#
|
357
371
|
# The given arguments may also be specified as matcher procs that return a
|
358
372
|
# boolean value indicating whether a job's attribute meets certain criteria.
|
359
373
|
#
|
@@ -390,6 +404,8 @@ module ActiveJob
|
|
390
404
|
# end
|
391
405
|
# end
|
392
406
|
def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil, priority: nil, &block)
|
407
|
+
require_active_job_test_adapter!("assert_enqueued_with")
|
408
|
+
|
393
409
|
expected = { job: job, args: args, at: at, queue: queue, priority: priority }.compact
|
394
410
|
expected_args = prepare_args_for_assertion(expected)
|
395
411
|
potential_matches = []
|
@@ -492,6 +508,8 @@ module ActiveJob
|
|
492
508
|
# end
|
493
509
|
# end
|
494
510
|
def assert_performed_with(job: nil, args: nil, at: nil, queue: nil, priority: nil, &block)
|
511
|
+
require_active_job_test_adapter!("assert_performed_with")
|
512
|
+
|
495
513
|
expected = { job: job, args: args, at: at, queue: queue, priority: priority }.compact
|
496
514
|
expected_args = prepare_args_for_assertion(expected)
|
497
515
|
potential_matches = []
|
@@ -593,10 +611,19 @@ module ActiveJob
|
|
593
611
|
# assert_performed_jobs 1
|
594
612
|
# end
|
595
613
|
#
|
596
|
-
# If the +:at+ option is specified, then only
|
597
|
-
#
|
614
|
+
# If the +:at+ option is specified, then only jobs that have been enqueued
|
615
|
+
# to run at or before the given time will be performed. This includes jobs
|
616
|
+
# that have been enqueued without a time.
|
617
|
+
#
|
618
|
+
# If queue_adapter_for_test is overridden to return a different adapter,
|
619
|
+
# +perform_enqueued_jobs+ will merely execute the block.
|
598
620
|
def perform_enqueued_jobs(only: nil, except: nil, queue: nil, at: nil, &block)
|
599
|
-
|
621
|
+
unless block_given?
|
622
|
+
require_active_job_test_adapter!("perform_enqueued_jobs (without a block)")
|
623
|
+
return flush_enqueued_jobs(only: only, except: except, queue: queue, at: at)
|
624
|
+
end
|
625
|
+
|
626
|
+
return _assert_nothing_raised_or_warn("perform_enqueued_jobs", &block) unless using_test_adapter?
|
600
627
|
|
601
628
|
validate_option(only: only, except: except)
|
602
629
|
|
@@ -636,12 +663,22 @@ module ActiveJob
|
|
636
663
|
end
|
637
664
|
|
638
665
|
private
|
666
|
+
def require_active_job_test_adapter!(method)
|
667
|
+
unless using_test_adapter?
|
668
|
+
raise ArgumentError.new("#{method} requires the Active Job test adapter, you're using #{queue_adapter.class.name}.")
|
669
|
+
end
|
670
|
+
end
|
671
|
+
|
672
|
+
def using_test_adapter?
|
673
|
+
queue_adapter.is_a?(ActiveJob::QueueAdapters::TestAdapter)
|
674
|
+
end
|
675
|
+
|
639
676
|
def clear_enqueued_jobs
|
640
|
-
enqueued_jobs.clear
|
677
|
+
enqueued_jobs.clear if using_test_adapter?
|
641
678
|
end
|
642
679
|
|
643
680
|
def clear_performed_jobs
|
644
|
-
performed_jobs.clear
|
681
|
+
performed_jobs.clear if using_test_adapter?
|
645
682
|
end
|
646
683
|
|
647
684
|
def jobs_with(jobs, only: nil, except: nil, queue: nil, at: nil)
|
@@ -694,6 +731,10 @@ module ActiveJob
|
|
694
731
|
|
695
732
|
def prepare_args_for_assertion(args)
|
696
733
|
args.dup.tap do |arguments|
|
734
|
+
if arguments[:queue].is_a?(Symbol)
|
735
|
+
arguments[:queue] = arguments[:queue].to_s
|
736
|
+
end
|
737
|
+
|
697
738
|
if arguments[:at].acts_like?(:time)
|
698
739
|
at_range = arguments[:at] - 1..arguments[:at] + 1
|
699
740
|
arguments[:at] = ->(at) { at_range.cover?(at) }
|
data/lib/active_job/version.rb
CHANGED
data/lib/active_job.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c)
|
4
|
+
# Copyright (c) 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
|
@@ -26,16 +26,46 @@
|
|
26
26
|
require "active_support"
|
27
27
|
require "active_support/rails"
|
28
28
|
require "active_job/version"
|
29
|
+
require "active_job/deprecator"
|
29
30
|
require "global_id"
|
30
31
|
|
32
|
+
# :markup: markdown
|
33
|
+
# :include: ../README.md
|
31
34
|
module ActiveJob
|
32
35
|
extend ActiveSupport::Autoload
|
33
36
|
|
34
37
|
autoload :Base
|
35
38
|
autoload :QueueAdapters
|
36
|
-
autoload :
|
37
|
-
autoload :
|
39
|
+
autoload :Arguments
|
40
|
+
autoload :DeserializationError, "active_job/arguments"
|
41
|
+
autoload :SerializationError, "active_job/arguments"
|
42
|
+
autoload :EnqueueAfterTransactionCommit
|
43
|
+
|
44
|
+
eager_autoload do
|
45
|
+
autoload :Serializers
|
46
|
+
autoload :ConfiguredJob
|
47
|
+
end
|
48
|
+
|
38
49
|
autoload :TestCase
|
39
50
|
autoload :TestHelper
|
40
|
-
|
51
|
+
|
52
|
+
def self.use_big_decimal_serializer
|
53
|
+
ActiveJob.deprecator.warn <<-WARNING.squish
|
54
|
+
Rails.application.config.active_job.use_big_decimal_serializer is deprecated and will be removed in Rails 8.0.
|
55
|
+
WARNING
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.use_big_decimal_serializer=(value)
|
59
|
+
ActiveJob.deprecator.warn <<-WARNING.squish
|
60
|
+
Rails.application.config.active_job.use_big_decimal_serializer is deprecated and will be removed in Rails 8.0.
|
61
|
+
WARNING
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# :singleton-method: verbose_enqueue_logs
|
66
|
+
#
|
67
|
+
# Specifies if the methods calling background job enqueue should be logged below
|
68
|
+
# their relevant enqueue log lines. Defaults to false.
|
69
|
+
singleton_class.attr_accessor :verbose_enqueue_logs
|
70
|
+
self.verbose_enqueue_logs = false
|
41
71
|
end
|