activejob_backport 0.0.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 +7 -0
- data/CHANGELOG.md +1 -0
- data/MIT-LICENSE +21 -0
- data/README.md +17 -0
- data/lib/active_job.rb +39 -0
- data/lib/active_job/arguments.rb +81 -0
- data/lib/active_job/base.rb +21 -0
- data/lib/active_job/callbacks.rb +144 -0
- data/lib/active_job/configured_job.rb +16 -0
- data/lib/active_job/core.rb +89 -0
- data/lib/active_job/enqueuing.rb +75 -0
- data/lib/active_job/execution.rb +41 -0
- data/lib/active_job/gem_version.rb +15 -0
- data/lib/active_job/logging.rb +121 -0
- data/lib/active_job/queue_adapter.rb +29 -0
- data/lib/active_job/queue_adapters.rb +17 -0
- data/lib/active_job/queue_adapters/backburner_adapter.rb +26 -0
- data/lib/active_job/queue_adapters/delayed_job_adapter.rb +23 -0
- data/lib/active_job/queue_adapters/inline_adapter.rb +15 -0
- data/lib/active_job/queue_adapters/qu_adapter.rb +29 -0
- data/lib/active_job/queue_adapters/que_adapter.rb +23 -0
- data/lib/active_job/queue_adapters/queue_classic_adapter.rb +40 -0
- data/lib/active_job/queue_adapters/resque_adapter.rb +41 -0
- data/lib/active_job/queue_adapters/sidekiq_adapter.rb +35 -0
- data/lib/active_job/queue_adapters/sneakers_adapter.rb +34 -0
- data/lib/active_job/queue_adapters/sucker_punch_adapter.rb +25 -0
- data/lib/active_job/queue_adapters/test_adapter.rb +37 -0
- data/lib/active_job/queue_name.rb +39 -0
- data/lib/active_job/railtie.rb +23 -0
- data/lib/active_job/test_case.rb +7 -0
- data/lib/active_job/test_helper.rb +196 -0
- data/lib/active_job/version.rb +8 -0
- data/lib/activejob_backport.rb +1 -0
- data/lib/global_id.rb +6 -0
- data/lib/global_id/global_id.rb +93 -0
- data/lib/global_id/identification.rb +13 -0
- data/lib/global_id/locator.rb +83 -0
- data/lib/rails/generators/job/job_generator.rb +24 -0
- data/lib/rails/generators/job/templates/job.rb +9 -0
- metadata +124 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'resque'
|
2
|
+
require 'active_support/core_ext/enumerable'
|
3
|
+
require 'active_support/core_ext/array/access'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'resque-scheduler'
|
7
|
+
rescue LoadError
|
8
|
+
begin
|
9
|
+
require 'resque_scheduler'
|
10
|
+
rescue LoadError
|
11
|
+
false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module ActiveJob
|
16
|
+
module QueueAdapters
|
17
|
+
class ResqueAdapter
|
18
|
+
class << self
|
19
|
+
def enqueue(job)
|
20
|
+
Resque.enqueue_to job.queue_name, JobWrapper, job.serialize
|
21
|
+
end
|
22
|
+
|
23
|
+
def enqueue_at(job, timestamp)
|
24
|
+
unless Resque.respond_to?(:enqueue_at_with_queue)
|
25
|
+
raise NotImplementedError, "To be able to schedule jobs with Resque you need the " \
|
26
|
+
"resque-scheduler gem. Please add it to your Gemfile and run bundle install"
|
27
|
+
end
|
28
|
+
Resque.enqueue_at_with_queue job.queue_name, timestamp, JobWrapper, job.serialize
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class JobWrapper
|
33
|
+
class << self
|
34
|
+
def perform(job_data)
|
35
|
+
Base.execute job_data
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'sidekiq'
|
2
|
+
|
3
|
+
module ActiveJob
|
4
|
+
module QueueAdapters
|
5
|
+
class SidekiqAdapter
|
6
|
+
class << self
|
7
|
+
def enqueue(job)
|
8
|
+
#Sidekiq::Client does not support symbols as keys
|
9
|
+
Sidekiq::Client.push \
|
10
|
+
'class' => JobWrapper,
|
11
|
+
'queue' => job.queue_name,
|
12
|
+
'args' => [ job.serialize ],
|
13
|
+
'retry' => true
|
14
|
+
end
|
15
|
+
|
16
|
+
def enqueue_at(job, timestamp)
|
17
|
+
Sidekiq::Client.push \
|
18
|
+
'class' => JobWrapper,
|
19
|
+
'queue' => job.queue_name,
|
20
|
+
'args' => [ job.serialize ],
|
21
|
+
'retry' => true,
|
22
|
+
'at' => timestamp
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class JobWrapper
|
27
|
+
include Sidekiq::Worker
|
28
|
+
|
29
|
+
def perform(job_data)
|
30
|
+
Base.execute job_data
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'sneakers'
|
2
|
+
require 'thread'
|
3
|
+
|
4
|
+
module ActiveJob
|
5
|
+
module QueueAdapters
|
6
|
+
class SneakersAdapter
|
7
|
+
@monitor = Monitor.new
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def enqueue(job)
|
11
|
+
@monitor.synchronize do
|
12
|
+
JobWrapper.from_queue job.queue_name
|
13
|
+
JobWrapper.enqueue ActiveSupport::JSON.encode(job.serialize)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def enqueue_at(job, timestamp)
|
18
|
+
raise NotImplementedError
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class JobWrapper
|
23
|
+
include Sneakers::Worker
|
24
|
+
from_queue 'default'
|
25
|
+
|
26
|
+
def work(msg)
|
27
|
+
job_data = ActiveSupport::JSON.decode(msg)
|
28
|
+
Base.execute job_data
|
29
|
+
ack!
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'sucker_punch'
|
2
|
+
|
3
|
+
module ActiveJob
|
4
|
+
module QueueAdapters
|
5
|
+
class SuckerPunchAdapter
|
6
|
+
class << self
|
7
|
+
def enqueue(job)
|
8
|
+
JobWrapper.new.async.perform job.serialize
|
9
|
+
end
|
10
|
+
|
11
|
+
def enqueue_at(job, timestamp)
|
12
|
+
raise NotImplementedError
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class JobWrapper
|
17
|
+
include SuckerPunch::Job
|
18
|
+
|
19
|
+
def perform(job_data)
|
20
|
+
Base.execute job_data
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module ActiveJob
|
2
|
+
module QueueAdapters
|
3
|
+
class TestAdapter
|
4
|
+
delegate :name, to: :class
|
5
|
+
attr_accessor(:perform_enqueued_jobs, :perform_enqueued_at_jobs)
|
6
|
+
attr_writer(:enqueued_jobs, :performed_jobs)
|
7
|
+
|
8
|
+
# Provides a store of all the enqueued jobs with the TestAdapter so you can check them.
|
9
|
+
def enqueued_jobs
|
10
|
+
@enqueued_jobs ||= []
|
11
|
+
end
|
12
|
+
|
13
|
+
# Provides a store of all the performed jobs with the TestAdapter so you can check them.
|
14
|
+
def performed_jobs
|
15
|
+
@performed_jobs ||= []
|
16
|
+
end
|
17
|
+
|
18
|
+
def enqueue(job)
|
19
|
+
if perform_enqueued_jobs
|
20
|
+
performed_jobs << {job: job.class, args: job.arguments, queue: job.queue_name}
|
21
|
+
job.perform_now
|
22
|
+
else
|
23
|
+
enqueued_jobs << {job: job.class, args: job.arguments, queue: job.queue_name}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def enqueue_at(job, timestamp)
|
28
|
+
if perform_enqueued_at_jobs
|
29
|
+
performed_jobs << {job: job.class, args: job.arguments, queue: job.queue_name, at: timestamp}
|
30
|
+
job.perform_now
|
31
|
+
else
|
32
|
+
enqueued_jobs << {job: job.class, args: job.arguments, queue: job.queue_name, at: timestamp}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module ActiveJob
|
2
|
+
module QueueName
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
mattr_accessor(:queue_name_prefix)
|
7
|
+
mattr_accessor(:default_queue_name)
|
8
|
+
|
9
|
+
def queue_as(part_name=nil, &block)
|
10
|
+
if block_given?
|
11
|
+
self.queue_name = block
|
12
|
+
else
|
13
|
+
self.queue_name = queue_name_from_part(part_name)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def queue_name_from_part(part_name) #:nodoc:
|
18
|
+
queue_name = part_name.to_s.presence || default_queue_name
|
19
|
+
name_parts = [queue_name_prefix.presence, queue_name]
|
20
|
+
name_parts.compact.join('_')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
included do
|
25
|
+
class_attribute :queue_name, instance_accessor: false
|
26
|
+
self.default_queue_name = "default"
|
27
|
+
self.queue_name = default_queue_name
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns the name of the queue the job will be run on
|
31
|
+
def queue_name
|
32
|
+
if @queue_name.is_a?(Proc)
|
33
|
+
@queue_name = self.class.queue_name_from_part(instance_exec(&@queue_name))
|
34
|
+
end
|
35
|
+
@queue_name
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# require 'global_id/railtie'
|
2
|
+
require 'active_job'
|
3
|
+
|
4
|
+
module ActiveJob
|
5
|
+
# = Active Job Railtie
|
6
|
+
class Railtie < Rails::Railtie # :nodoc:
|
7
|
+
config.active_job = ActiveSupport::OrderedOptions.new
|
8
|
+
|
9
|
+
initializer 'active_job.logger' do
|
10
|
+
ActiveSupport.on_load(:active_job) { self.logger = ::Rails.logger }
|
11
|
+
end
|
12
|
+
|
13
|
+
initializer "active_job.set_configs" do |app|
|
14
|
+
options = app.config.active_job
|
15
|
+
options.queue_adapter ||= :inline
|
16
|
+
|
17
|
+
ActiveSupport.on_load(:active_job) do
|
18
|
+
options.each { |k,v| send("#{k}=", v) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
module ActiveJob
|
2
|
+
# Provides helper methods for testing Active Job
|
3
|
+
module TestHelper
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
def before_setup
|
8
|
+
@old_queue_adapter = queue_adapter
|
9
|
+
ActiveJob::Base.queue_adapter = :test
|
10
|
+
clear_enqueued_jobs
|
11
|
+
clear_performed_jobs
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def after_teardown
|
16
|
+
super
|
17
|
+
ActiveJob::Base.queue_adapter = @old_queue_adapter
|
18
|
+
end
|
19
|
+
|
20
|
+
# Asserts that the number of enqueued jobs matches the given number.
|
21
|
+
#
|
22
|
+
# def test_jobs
|
23
|
+
# assert_enqueued_jobs 0
|
24
|
+
# HelloJob.perform_later('david')
|
25
|
+
# assert_enqueued_jobs 1
|
26
|
+
# HelloJob.perform_later('abdelkader')
|
27
|
+
# assert_enqueued_jobs 2
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# If a block is passed, that block should cause the specified number of
|
31
|
+
# jobs to be enqueued.
|
32
|
+
#
|
33
|
+
# def test_jobs_again
|
34
|
+
# assert_enqueued_jobs 1 do
|
35
|
+
# HelloJob.perform_later('cristian')
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# assert_enqueued_jobs 2 do
|
39
|
+
# HelloJob.perform_later('aaron')
|
40
|
+
# HelloJob.perform_later('rafael')
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
def assert_enqueued_jobs(number)
|
44
|
+
if block_given?
|
45
|
+
original_count = enqueued_jobs.size
|
46
|
+
yield
|
47
|
+
new_count = enqueued_jobs.size
|
48
|
+
assert_equal original_count + number, new_count,
|
49
|
+
"#{number} jobs expected, but #{new_count - original_count} were enqueued"
|
50
|
+
else
|
51
|
+
enqueued_jobs_size = enqueued_jobs.size
|
52
|
+
assert_equal number, enqueued_jobs_size, "#{number} jobs expected, but #{enqueued_jobs_size} were enqueued"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Assert that no job have been enqueued.
|
57
|
+
#
|
58
|
+
# def test_jobs
|
59
|
+
# assert_no_enqueued_jobs
|
60
|
+
# HelloJob.perform_later('jeremy')
|
61
|
+
# assert_enqueued_jobs 1
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# If a block is passed, that block should not cause any job to be enqueued.
|
65
|
+
#
|
66
|
+
# def test_jobs_again
|
67
|
+
# assert_no_enqueued_jobs do
|
68
|
+
# # No job should be enqueued from this block
|
69
|
+
# end
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# Note: This assertion is simply a shortcut for:
|
73
|
+
#
|
74
|
+
# assert_enqueued_jobs 0
|
75
|
+
def assert_no_enqueued_jobs(&block)
|
76
|
+
assert_enqueued_jobs 0, &block
|
77
|
+
end
|
78
|
+
|
79
|
+
# Asserts that the number of performed jobs matches the given number.
|
80
|
+
#
|
81
|
+
# def test_jobs
|
82
|
+
# assert_performed_jobs 0
|
83
|
+
# HelloJob.perform_later('xavier')
|
84
|
+
# assert_performed_jobs 1
|
85
|
+
# HelloJob.perform_later('yves')
|
86
|
+
# assert_performed_jobs 2
|
87
|
+
# end
|
88
|
+
#
|
89
|
+
# If a block is passed, that block should cause the specified number of
|
90
|
+
# jobs to be performed.
|
91
|
+
#
|
92
|
+
# def test_jobs_again
|
93
|
+
# assert_performed_jobs 1 do
|
94
|
+
# HelloJob.perform_later('robin')
|
95
|
+
# end
|
96
|
+
#
|
97
|
+
# assert_performed_jobs 2 do
|
98
|
+
# HelloJob.perform_later('carlos')
|
99
|
+
# HelloJob.perform_later('sean')
|
100
|
+
# end
|
101
|
+
# end
|
102
|
+
def assert_performed_jobs(number)
|
103
|
+
if block_given?
|
104
|
+
original_count = performed_jobs.size
|
105
|
+
yield
|
106
|
+
new_count = performed_jobs.size
|
107
|
+
assert_equal original_count + number, new_count,
|
108
|
+
"#{number} jobs expected, but #{new_count - original_count} were performed"
|
109
|
+
else
|
110
|
+
performed_jobs_size = performed_jobs.size
|
111
|
+
assert_equal number, performed_jobs_size, "#{number} jobs expected, but #{performed_jobs_size} were performed"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Asserts that no jobs have been performed.
|
116
|
+
#
|
117
|
+
# def test_jobs
|
118
|
+
# assert_no_performed_jobs
|
119
|
+
# HelloJob.perform_later('matthew')
|
120
|
+
# assert_performed_jobs 1
|
121
|
+
# end
|
122
|
+
#
|
123
|
+
# If a block is passed, that block should not cause any job to be performed.
|
124
|
+
#
|
125
|
+
# def test_jobs_again
|
126
|
+
# assert_no_performed_jobs do
|
127
|
+
# # No job should be performed from this block
|
128
|
+
# end
|
129
|
+
# end
|
130
|
+
#
|
131
|
+
# Note: This assertion is simply a shortcut for:
|
132
|
+
#
|
133
|
+
# assert_performed_jobs 0
|
134
|
+
def assert_no_performed_jobs(&block)
|
135
|
+
assert_performed_jobs 0, &block
|
136
|
+
end
|
137
|
+
|
138
|
+
# Asserts that the job passed in the block has been enqueued with the given arguments.
|
139
|
+
#
|
140
|
+
# def assert_enqueued_job
|
141
|
+
# assert_enqueued_with(job: MyJob, args: [1,2,3], queue: 'low') do
|
142
|
+
# MyJob.perform_later(1,2,3)
|
143
|
+
# end
|
144
|
+
# end
|
145
|
+
def assert_enqueued_with(args = {}, &_block)
|
146
|
+
original_enqueued_jobs = enqueued_jobs.dup
|
147
|
+
clear_enqueued_jobs
|
148
|
+
args.assert_valid_keys(:job, :args, :at, :queue)
|
149
|
+
yield
|
150
|
+
matching_job = enqueued_jobs.any? do |job|
|
151
|
+
args.all? { |key, value| value == job[key] }
|
152
|
+
end
|
153
|
+
assert matching_job
|
154
|
+
ensure
|
155
|
+
queue_adapter.enqueued_jobs = original_enqueued_jobs + enqueued_jobs
|
156
|
+
end
|
157
|
+
|
158
|
+
# Asserts that the job passed in the block has been performed with the given arguments.
|
159
|
+
#
|
160
|
+
# def test_assert_performed_with
|
161
|
+
# assert_performed_with(job: MyJob, args: [1,2,3], queue: 'high') do
|
162
|
+
# MyJob.perform_later(1,2,3)
|
163
|
+
# end
|
164
|
+
# end
|
165
|
+
def assert_performed_with(args = {}, &_block)
|
166
|
+
original_performed_jobs = performed_jobs.dup
|
167
|
+
clear_performed_jobs
|
168
|
+
args.assert_valid_keys(:job, :args, :at, :queue)
|
169
|
+
yield
|
170
|
+
matching_job = performed_jobs.any? do |job|
|
171
|
+
args.all? { |key, value| value == job[key] }
|
172
|
+
end
|
173
|
+
assert matching_job, "No performed job found with #{args}"
|
174
|
+
ensure
|
175
|
+
queue_adapter.performed_jobs = original_performed_jobs + performed_jobs
|
176
|
+
end
|
177
|
+
|
178
|
+
def queue_adapter
|
179
|
+
ActiveJob::Base.queue_adapter
|
180
|
+
end
|
181
|
+
|
182
|
+
delegate :enqueued_jobs, :enqueued_jobs=,
|
183
|
+
:performed_jobs, :performed_jobs=,
|
184
|
+
to: :queue_adapter
|
185
|
+
|
186
|
+
private
|
187
|
+
def clear_enqueued_jobs
|
188
|
+
enqueued_jobs.clear
|
189
|
+
end
|
190
|
+
|
191
|
+
def clear_performed_jobs
|
192
|
+
performed_jobs.clear
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|