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.
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