activejob_backport 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.md +17 -0
  5. data/lib/active_job.rb +39 -0
  6. data/lib/active_job/arguments.rb +81 -0
  7. data/lib/active_job/base.rb +21 -0
  8. data/lib/active_job/callbacks.rb +144 -0
  9. data/lib/active_job/configured_job.rb +16 -0
  10. data/lib/active_job/core.rb +89 -0
  11. data/lib/active_job/enqueuing.rb +75 -0
  12. data/lib/active_job/execution.rb +41 -0
  13. data/lib/active_job/gem_version.rb +15 -0
  14. data/lib/active_job/logging.rb +121 -0
  15. data/lib/active_job/queue_adapter.rb +29 -0
  16. data/lib/active_job/queue_adapters.rb +17 -0
  17. data/lib/active_job/queue_adapters/backburner_adapter.rb +26 -0
  18. data/lib/active_job/queue_adapters/delayed_job_adapter.rb +23 -0
  19. data/lib/active_job/queue_adapters/inline_adapter.rb +15 -0
  20. data/lib/active_job/queue_adapters/qu_adapter.rb +29 -0
  21. data/lib/active_job/queue_adapters/que_adapter.rb +23 -0
  22. data/lib/active_job/queue_adapters/queue_classic_adapter.rb +40 -0
  23. data/lib/active_job/queue_adapters/resque_adapter.rb +41 -0
  24. data/lib/active_job/queue_adapters/sidekiq_adapter.rb +35 -0
  25. data/lib/active_job/queue_adapters/sneakers_adapter.rb +34 -0
  26. data/lib/active_job/queue_adapters/sucker_punch_adapter.rb +25 -0
  27. data/lib/active_job/queue_adapters/test_adapter.rb +37 -0
  28. data/lib/active_job/queue_name.rb +39 -0
  29. data/lib/active_job/railtie.rb +23 -0
  30. data/lib/active_job/test_case.rb +7 -0
  31. data/lib/active_job/test_helper.rb +196 -0
  32. data/lib/active_job/version.rb +8 -0
  33. data/lib/activejob_backport.rb +1 -0
  34. data/lib/global_id.rb +6 -0
  35. data/lib/global_id/global_id.rb +93 -0
  36. data/lib/global_id/identification.rb +13 -0
  37. data/lib/global_id/locator.rb +83 -0
  38. data/lib/rails/generators/job/job_generator.rb +24 -0
  39. data/lib/rails/generators/job/templates/job.rb +9 -0
  40. 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,7 @@
1
+ require 'active_support/test_case'
2
+
3
+ module ActiveJob
4
+ class TestCase < ActiveSupport::TestCase
5
+ include ActiveJob::TestHelper
6
+ end
7
+ 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