sidekiq 5.2.10 → 7.2.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sidekiq might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Changes.md +600 -8
- data/LICENSE.txt +9 -0
- data/README.md +47 -50
- data/bin/sidekiq +22 -3
- data/bin/sidekiqload +213 -115
- data/bin/sidekiqmon +11 -0
- data/lib/generators/sidekiq/job_generator.rb +57 -0
- data/lib/generators/sidekiq/templates/{worker.rb.erb → job.rb.erb} +2 -2
- data/lib/generators/sidekiq/templates/{worker_spec.rb.erb → job_spec.rb.erb} +1 -1
- data/lib/generators/sidekiq/templates/{worker_test.rb.erb → job_test.rb.erb} +1 -1
- data/lib/sidekiq/api.rb +557 -354
- data/lib/sidekiq/capsule.rb +127 -0
- data/lib/sidekiq/cli.rb +204 -226
- data/lib/sidekiq/client.rb +127 -102
- data/lib/sidekiq/component.rb +68 -0
- data/lib/sidekiq/config.rb +287 -0
- data/lib/sidekiq/deploy.rb +62 -0
- data/lib/sidekiq/embedded.rb +61 -0
- data/lib/sidekiq/fetch.rb +49 -42
- data/lib/sidekiq/job.rb +374 -0
- data/lib/sidekiq/job_logger.rb +33 -7
- data/lib/sidekiq/job_retry.rb +147 -108
- data/lib/sidekiq/job_util.rb +107 -0
- data/lib/sidekiq/launcher.rb +203 -105
- data/lib/sidekiq/logger.rb +131 -0
- data/lib/sidekiq/manager.rb +43 -46
- data/lib/sidekiq/metrics/query.rb +155 -0
- data/lib/sidekiq/metrics/shared.rb +95 -0
- data/lib/sidekiq/metrics/tracking.rb +136 -0
- data/lib/sidekiq/middleware/chain.rb +113 -56
- data/lib/sidekiq/middleware/current_attributes.rb +95 -0
- data/lib/sidekiq/middleware/i18n.rb +7 -7
- data/lib/sidekiq/middleware/modules.rb +21 -0
- data/lib/sidekiq/monitor.rb +146 -0
- data/lib/sidekiq/paginator.rb +28 -16
- data/lib/sidekiq/processor.rb +122 -120
- data/lib/sidekiq/rails.rb +48 -38
- data/lib/sidekiq/redis_client_adapter.rb +111 -0
- data/lib/sidekiq/redis_connection.rb +39 -107
- data/lib/sidekiq/ring_buffer.rb +29 -0
- data/lib/sidekiq/scheduled.rb +111 -49
- data/lib/sidekiq/sd_notify.rb +149 -0
- data/lib/sidekiq/systemd.rb +24 -0
- data/lib/sidekiq/testing/inline.rb +6 -5
- data/lib/sidekiq/testing.rb +90 -89
- data/lib/sidekiq/transaction_aware_client.rb +44 -0
- data/lib/sidekiq/version.rb +3 -1
- data/lib/sidekiq/web/action.rb +15 -11
- data/lib/sidekiq/web/application.rb +186 -79
- data/lib/sidekiq/web/csrf_protection.rb +180 -0
- data/lib/sidekiq/web/helpers.rb +154 -115
- data/lib/sidekiq/web/router.rb +23 -19
- data/lib/sidekiq/web.rb +68 -107
- data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
- data/lib/sidekiq.rb +92 -182
- data/sidekiq.gemspec +25 -16
- data/web/assets/images/apple-touch-icon.png +0 -0
- data/web/assets/javascripts/application.js +146 -61
- data/web/assets/javascripts/base-charts.js +106 -0
- data/web/assets/javascripts/chart.min.js +13 -0
- data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
- data/web/assets/javascripts/dashboard-charts.js +182 -0
- data/web/assets/javascripts/dashboard.js +35 -293
- data/web/assets/javascripts/metrics.js +298 -0
- data/web/assets/stylesheets/application-dark.css +147 -0
- data/web/assets/stylesheets/application-rtl.css +2 -95
- data/web/assets/stylesheets/application.css +111 -522
- data/web/locales/ar.yml +71 -65
- data/web/locales/cs.yml +62 -62
- data/web/locales/da.yml +60 -53
- data/web/locales/de.yml +65 -53
- data/web/locales/el.yml +43 -24
- data/web/locales/en.yml +86 -66
- data/web/locales/es.yml +70 -54
- data/web/locales/fa.yml +65 -65
- data/web/locales/fr.yml +83 -62
- data/web/locales/gd.yml +99 -0
- data/web/locales/he.yml +65 -64
- data/web/locales/hi.yml +59 -59
- data/web/locales/it.yml +53 -53
- data/web/locales/ja.yml +75 -64
- data/web/locales/ko.yml +52 -52
- data/web/locales/lt.yml +83 -0
- data/web/locales/nb.yml +61 -61
- data/web/locales/nl.yml +52 -52
- data/web/locales/pl.yml +45 -45
- data/web/locales/pt-br.yml +83 -55
- data/web/locales/pt.yml +51 -51
- data/web/locales/ru.yml +68 -63
- data/web/locales/sv.yml +53 -53
- data/web/locales/ta.yml +60 -60
- data/web/locales/uk.yml +62 -61
- data/web/locales/ur.yml +64 -64
- data/web/locales/vi.yml +83 -0
- data/web/locales/zh-cn.yml +43 -16
- data/web/locales/zh-tw.yml +42 -8
- data/web/views/_footer.erb +6 -3
- data/web/views/_job_info.erb +21 -4
- data/web/views/_metrics_period_select.erb +12 -0
- data/web/views/_nav.erb +1 -1
- data/web/views/_paging.erb +2 -0
- data/web/views/_poll_link.erb +3 -6
- data/web/views/_summary.erb +7 -7
- data/web/views/busy.erb +77 -27
- data/web/views/dashboard.erb +48 -18
- data/web/views/dead.erb +3 -3
- data/web/views/filtering.erb +7 -0
- data/web/views/layout.erb +3 -1
- data/web/views/metrics.erb +91 -0
- data/web/views/metrics_for_job.erb +59 -0
- data/web/views/morgue.erb +14 -15
- data/web/views/queue.erb +33 -24
- data/web/views/queues.erb +19 -5
- data/web/views/retries.erb +16 -17
- data/web/views/retry.erb +3 -3
- data/web/views/scheduled.erb +17 -15
- metadata +71 -71
- data/.circleci/config.yml +0 -61
- data/.github/contributing.md +0 -32
- data/.github/issue_template.md +0 -11
- data/.gitignore +0 -15
- data/.travis.yml +0 -11
- data/3.0-Upgrade.md +0 -70
- data/4.0-Upgrade.md +0 -53
- data/5.0-Upgrade.md +0 -56
- data/COMM-LICENSE +0 -97
- data/Ent-Changes.md +0 -238
- data/Gemfile +0 -19
- data/LICENSE +0 -9
- data/Pro-2.0-Upgrade.md +0 -138
- data/Pro-3.0-Upgrade.md +0 -44
- data/Pro-4.0-Upgrade.md +0 -35
- data/Pro-Changes.md +0 -759
- data/Rakefile +0 -9
- data/bin/sidekiqctl +0 -20
- data/code_of_conduct.md +0 -50
- data/lib/generators/sidekiq/worker_generator.rb +0 -49
- data/lib/sidekiq/core_ext.rb +0 -1
- data/lib/sidekiq/ctl.rb +0 -221
- data/lib/sidekiq/delay.rb +0 -42
- data/lib/sidekiq/exception_handler.rb +0 -29
- data/lib/sidekiq/extensions/action_mailer.rb +0 -57
- data/lib/sidekiq/extensions/active_record.rb +0 -40
- data/lib/sidekiq/extensions/class_methods.rb +0 -40
- data/lib/sidekiq/extensions/generic_proxy.rb +0 -31
- data/lib/sidekiq/logging.rb +0 -122
- data/lib/sidekiq/middleware/server/active_record.rb +0 -23
- data/lib/sidekiq/util.rb +0 -66
- data/lib/sidekiq/worker.rb +0 -220
data/lib/sidekiq/testing.rb
CHANGED
@@ -1,27 +1,46 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require 'securerandom'
|
3
|
-
require 'sidekiq'
|
4
2
|
|
5
|
-
|
3
|
+
require "securerandom"
|
4
|
+
require "sidekiq"
|
6
5
|
|
6
|
+
module Sidekiq
|
7
7
|
class Testing
|
8
|
+
class TestModeAlreadySetError < RuntimeError; end
|
8
9
|
class << self
|
9
|
-
attr_accessor :
|
10
|
+
attr_accessor :__global_test_mode
|
10
11
|
|
12
|
+
# Calling without a block sets the global test mode, affecting
|
13
|
+
# all threads. Calling with a block only affects the current Thread.
|
11
14
|
def __set_test_mode(mode)
|
12
15
|
if block_given?
|
13
|
-
|
16
|
+
# Reentrant testing modes will lead to a rat's nest of code which is
|
17
|
+
# hard to reason about. You can set the testing mode once globally and
|
18
|
+
# you can override that global setting once per-thread.
|
19
|
+
raise TestModeAlreadySetError, "Nesting test modes is not supported" if __local_test_mode
|
20
|
+
|
21
|
+
self.__local_test_mode = mode
|
14
22
|
begin
|
15
|
-
self.__test_mode = mode
|
16
23
|
yield
|
17
24
|
ensure
|
18
|
-
self.
|
25
|
+
self.__local_test_mode = nil
|
19
26
|
end
|
20
27
|
else
|
21
|
-
self.
|
28
|
+
self.__global_test_mode = mode
|
22
29
|
end
|
23
30
|
end
|
24
31
|
|
32
|
+
def __test_mode
|
33
|
+
__local_test_mode || __global_test_mode
|
34
|
+
end
|
35
|
+
|
36
|
+
def __local_test_mode
|
37
|
+
Thread.current[:__sidekiq_test_mode]
|
38
|
+
end
|
39
|
+
|
40
|
+
def __local_test_mode=(value)
|
41
|
+
Thread.current[:__sidekiq_test_mode] = value
|
42
|
+
end
|
43
|
+
|
25
44
|
def disable!(&block)
|
26
45
|
__set_test_mode(:disable, &block)
|
27
46
|
end
|
@@ -35,35 +54,26 @@ module Sidekiq
|
|
35
54
|
end
|
36
55
|
|
37
56
|
def enabled?
|
38
|
-
|
57
|
+
__test_mode != :disable
|
39
58
|
end
|
40
59
|
|
41
60
|
def disabled?
|
42
|
-
|
61
|
+
__test_mode == :disable
|
43
62
|
end
|
44
63
|
|
45
64
|
def fake?
|
46
|
-
|
65
|
+
__test_mode == :fake
|
47
66
|
end
|
48
67
|
|
49
68
|
def inline?
|
50
|
-
|
69
|
+
__test_mode == :inline
|
51
70
|
end
|
52
71
|
|
53
72
|
def server_middleware
|
54
|
-
@server_chain ||= Middleware::Chain.new
|
73
|
+
@server_chain ||= Middleware::Chain.new(Sidekiq.default_configuration)
|
55
74
|
yield @server_chain if block_given?
|
56
75
|
@server_chain
|
57
76
|
end
|
58
|
-
|
59
|
-
def constantize(str)
|
60
|
-
names = str.split('::')
|
61
|
-
names.shift if names.empty? || names.first.empty?
|
62
|
-
|
63
|
-
names.inject(Object) do |constant, name|
|
64
|
-
constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
65
|
-
end
|
66
|
-
end
|
67
77
|
end
|
68
78
|
end
|
69
79
|
|
@@ -73,18 +83,18 @@ module Sidekiq
|
|
73
83
|
class EmptyQueueError < RuntimeError; end
|
74
84
|
|
75
85
|
module TestingClient
|
76
|
-
def
|
86
|
+
def atomic_push(conn, payloads)
|
77
87
|
if Sidekiq::Testing.fake?
|
78
88
|
payloads.each do |job|
|
79
89
|
job = Sidekiq.load_json(Sidekiq.dump_json(job))
|
80
|
-
job
|
81
|
-
Queues.push(job[
|
90
|
+
job["enqueued_at"] = Time.now.to_f unless job["at"]
|
91
|
+
Queues.push(job["queue"], job["class"], job)
|
82
92
|
end
|
83
93
|
true
|
84
94
|
elsif Sidekiq::Testing.inline?
|
85
95
|
payloads.each do |job|
|
86
|
-
klass =
|
87
|
-
job[
|
96
|
+
klass = Object.const_get(job["class"])
|
97
|
+
job["id"] ||= SecureRandom.hex(12)
|
88
98
|
job_hash = Sidekiq.load_json(Sidekiq.dump_json(job))
|
89
99
|
klass.process_job(job_hash)
|
90
100
|
end
|
@@ -101,20 +111,20 @@ module Sidekiq
|
|
101
111
|
##
|
102
112
|
# The Queues class is only for testing the fake queue implementation.
|
103
113
|
# There are 2 data structures involved in tandem. This is due to the
|
104
|
-
# Rspec syntax of change(
|
114
|
+
# Rspec syntax of change(HardJob.jobs, :size). It keeps a reference
|
105
115
|
# to the array. Because the array was dervied from a filter of the total
|
106
116
|
# jobs enqueued, it appeared as though the array didn't change.
|
107
117
|
#
|
108
118
|
# To solve this, we'll keep 2 hashes containing the jobs. One with keys based
|
109
|
-
# on the queue, and another with keys of the
|
110
|
-
#
|
119
|
+
# on the queue, and another with keys of the job type, so the array for
|
120
|
+
# HardJob.jobs is a straight reference to a real array.
|
111
121
|
#
|
112
122
|
# Queue-based hash:
|
113
123
|
#
|
114
124
|
# {
|
115
125
|
# "default"=>[
|
116
126
|
# {
|
117
|
-
# "class"=>"TestTesting::
|
127
|
+
# "class"=>"TestTesting::HardJob",
|
118
128
|
# "args"=>[1, 2],
|
119
129
|
# "retry"=>true,
|
120
130
|
# "queue"=>"default",
|
@@ -124,12 +134,12 @@ module Sidekiq
|
|
124
134
|
# ]
|
125
135
|
# }
|
126
136
|
#
|
127
|
-
#
|
137
|
+
# Job-based hash:
|
128
138
|
#
|
129
139
|
# {
|
130
|
-
# "TestTesting::
|
140
|
+
# "TestTesting::HardJob"=>[
|
131
141
|
# {
|
132
|
-
# "class"=>"TestTesting::
|
142
|
+
# "class"=>"TestTesting::HardJob",
|
133
143
|
# "args"=>[1, 2],
|
134
144
|
# "retry"=>true,
|
135
145
|
# "queue"=>"default",
|
@@ -144,14 +154,14 @@ module Sidekiq
|
|
144
154
|
# require 'sidekiq/testing'
|
145
155
|
#
|
146
156
|
# assert_equal 0, Sidekiq::Queues["default"].size
|
147
|
-
#
|
157
|
+
# HardJob.perform_async(:something)
|
148
158
|
# assert_equal 1, Sidekiq::Queues["default"].size
|
149
159
|
# assert_equal :something, Sidekiq::Queues["default"].first['args'][0]
|
150
160
|
#
|
151
|
-
# You can also clear all
|
161
|
+
# You can also clear all jobs:
|
152
162
|
#
|
153
163
|
# assert_equal 0, Sidekiq::Queues["default"].size
|
154
|
-
#
|
164
|
+
# HardJob.perform_async(:something)
|
155
165
|
# Sidekiq::Queues.clear_all
|
156
166
|
# assert_equal 0, Sidekiq::Queues["default"].size
|
157
167
|
#
|
@@ -170,35 +180,36 @@ module Sidekiq
|
|
170
180
|
|
171
181
|
def push(queue, klass, job)
|
172
182
|
jobs_by_queue[queue] << job
|
173
|
-
|
183
|
+
jobs_by_class[klass] << job
|
174
184
|
end
|
175
185
|
|
176
186
|
def jobs_by_queue
|
177
187
|
@jobs_by_queue ||= Hash.new { |hash, key| hash[key] = [] }
|
178
188
|
end
|
179
189
|
|
180
|
-
def
|
181
|
-
@
|
190
|
+
def jobs_by_class
|
191
|
+
@jobs_by_class ||= Hash.new { |hash, key| hash[key] = [] }
|
182
192
|
end
|
193
|
+
alias_method :jobs_by_worker, :jobs_by_class
|
183
194
|
|
184
195
|
def delete_for(jid, queue, klass)
|
185
196
|
jobs_by_queue[queue.to_s].delete_if { |job| job["jid"] == jid }
|
186
|
-
|
197
|
+
jobs_by_class[klass].delete_if { |job| job["jid"] == jid }
|
187
198
|
end
|
188
199
|
|
189
200
|
def clear_for(queue, klass)
|
190
|
-
jobs_by_queue[queue].clear
|
191
|
-
|
201
|
+
jobs_by_queue[queue.to_s].clear
|
202
|
+
jobs_by_class[klass].clear
|
192
203
|
end
|
193
204
|
|
194
205
|
def clear_all
|
195
206
|
jobs_by_queue.clear
|
196
|
-
|
207
|
+
jobs_by_class.clear
|
197
208
|
end
|
198
209
|
end
|
199
210
|
end
|
200
211
|
|
201
|
-
module
|
212
|
+
module Job
|
202
213
|
##
|
203
214
|
# The Sidekiq testing infrastructure overrides perform_async
|
204
215
|
# so that it does not actually touch the network. Instead it
|
@@ -212,70 +223,53 @@ module Sidekiq
|
|
212
223
|
#
|
213
224
|
# require 'sidekiq/testing'
|
214
225
|
#
|
215
|
-
# assert_equal 0,
|
216
|
-
#
|
217
|
-
# assert_equal 1,
|
218
|
-
# assert_equal :something,
|
219
|
-
#
|
220
|
-
# assert_equal 0, Sidekiq::Extensions::DelayedMailer.jobs.size
|
221
|
-
# MyMailer.delay.send_welcome_email('foo@example.com')
|
222
|
-
# assert_equal 1, Sidekiq::Extensions::DelayedMailer.jobs.size
|
223
|
-
#
|
224
|
-
# You can also clear and drain all workers' jobs:
|
225
|
-
#
|
226
|
-
# assert_equal 0, Sidekiq::Extensions::DelayedMailer.jobs.size
|
227
|
-
# assert_equal 0, Sidekiq::Extensions::DelayedModel.jobs.size
|
228
|
-
#
|
229
|
-
# MyMailer.delay.send_welcome_email('foo@example.com')
|
230
|
-
# MyModel.delay.do_something_hard
|
231
|
-
#
|
232
|
-
# assert_equal 1, Sidekiq::Extensions::DelayedMailer.jobs.size
|
233
|
-
# assert_equal 1, Sidekiq::Extensions::DelayedModel.jobs.size
|
226
|
+
# assert_equal 0, HardJob.jobs.size
|
227
|
+
# HardJob.perform_async(:something)
|
228
|
+
# assert_equal 1, HardJob.jobs.size
|
229
|
+
# assert_equal :something, HardJob.jobs[0]['args'][0]
|
234
230
|
#
|
235
|
-
#
|
231
|
+
# You can also clear and drain all job types:
|
236
232
|
#
|
237
|
-
#
|
238
|
-
# assert_equal 0, Sidekiq::Extensions::DelayedModel.jobs.size
|
233
|
+
# Sidekiq::Job.clear_all # or .drain_all
|
239
234
|
#
|
240
235
|
# This can be useful to make sure jobs don't linger between tests:
|
241
236
|
#
|
242
237
|
# RSpec.configure do |config|
|
243
238
|
# config.before(:each) do
|
244
|
-
# Sidekiq::
|
239
|
+
# Sidekiq::Job.clear_all
|
245
240
|
# end
|
246
241
|
# end
|
247
242
|
#
|
248
243
|
# or for acceptance testing, i.e. with cucumber:
|
249
244
|
#
|
250
245
|
# AfterStep do
|
251
|
-
# Sidekiq::
|
246
|
+
# Sidekiq::Job.drain_all
|
252
247
|
# end
|
253
248
|
#
|
254
249
|
# When I sign up as "foo@example.com"
|
255
250
|
# Then I should receive a welcome email to "foo@example.com"
|
256
251
|
#
|
257
252
|
module ClassMethods
|
258
|
-
|
259
253
|
# Queue for this worker
|
260
254
|
def queue
|
261
|
-
|
255
|
+
get_sidekiq_options["queue"]
|
262
256
|
end
|
263
257
|
|
264
258
|
# Jobs queued for this worker
|
265
259
|
def jobs
|
266
|
-
Queues.
|
260
|
+
Queues.jobs_by_class[to_s]
|
267
261
|
end
|
268
262
|
|
269
263
|
# Clear all jobs for this worker
|
270
264
|
def clear
|
271
|
-
Queues.clear_for(queue,
|
265
|
+
Queues.clear_for(queue, to_s)
|
272
266
|
end
|
273
267
|
|
274
268
|
# Drain and run all jobs for this worker
|
275
269
|
def drain
|
276
270
|
while jobs.any?
|
277
271
|
next_job = jobs.first
|
278
|
-
Queues.delete_for(next_job["jid"], next_job["queue"],
|
272
|
+
Queues.delete_for(next_job["jid"], next_job["queue"], to_s)
|
279
273
|
process_job(next_job)
|
280
274
|
end
|
281
275
|
end
|
@@ -284,16 +278,16 @@ module Sidekiq
|
|
284
278
|
def perform_one
|
285
279
|
raise(EmptyQueueError, "perform_one called with empty job queue") if jobs.empty?
|
286
280
|
next_job = jobs.first
|
287
|
-
Queues.delete_for(next_job["jid"], queue,
|
281
|
+
Queues.delete_for(next_job["jid"], queue, to_s)
|
288
282
|
process_job(next_job)
|
289
283
|
end
|
290
284
|
|
291
285
|
def process_job(job)
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
Sidekiq::Testing.server_middleware.invoke(
|
296
|
-
execute_job(
|
286
|
+
inst = new
|
287
|
+
inst.jid = job["jid"]
|
288
|
+
inst.bid = job["bid"] if inst.respond_to?(:bid=)
|
289
|
+
Sidekiq::Testing.server_middleware.invoke(inst, job, job["queue"]) do
|
290
|
+
execute_job(inst, job["args"])
|
297
291
|
end
|
298
292
|
end
|
299
293
|
|
@@ -307,27 +301,34 @@ module Sidekiq
|
|
307
301
|
Queues.jobs_by_queue.values.flatten
|
308
302
|
end
|
309
303
|
|
310
|
-
# Clear all queued jobs
|
304
|
+
# Clear all queued jobs
|
311
305
|
def clear_all
|
312
306
|
Queues.clear_all
|
313
307
|
end
|
314
308
|
|
315
|
-
# Drain all queued jobs
|
309
|
+
# Drain (execute) all queued jobs
|
316
310
|
def drain_all
|
317
311
|
while jobs.any?
|
318
|
-
|
312
|
+
job_classes = jobs.map { |job| job["class"] }.uniq
|
319
313
|
|
320
|
-
|
321
|
-
|
314
|
+
job_classes.each do |job_class|
|
315
|
+
Object.const_get(job_class).drain
|
322
316
|
end
|
323
317
|
end
|
324
318
|
end
|
325
319
|
end
|
326
320
|
end
|
321
|
+
|
322
|
+
module TestingExtensions
|
323
|
+
def jobs_for(klass)
|
324
|
+
jobs.select do |job|
|
325
|
+
marshalled = job["args"][0]
|
326
|
+
marshalled.index(klass.to_s) && YAML.safe_load(marshalled)[0] == klass
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
327
330
|
end
|
328
331
|
|
329
|
-
if defined?(::Rails) && Rails.respond_to?(:env) && !Rails.env.test?
|
330
|
-
|
331
|
-
puts("⛔️ WARNING: Sidekiq testing API enabled, but this is not the test environment. Your jobs will not go to Redis.")
|
332
|
-
puts("**************************************************")
|
332
|
+
if defined?(::Rails) && Rails.respond_to?(:env) && !Rails.env.test? && !$TESTING
|
333
|
+
warn("⛔️ WARNING: Sidekiq testing API enabled, but this is not the test environment. Your jobs will not go to Redis.", uplevel: 1)
|
333
334
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "securerandom"
|
4
|
+
require "sidekiq/client"
|
5
|
+
|
6
|
+
module Sidekiq
|
7
|
+
class TransactionAwareClient
|
8
|
+
def initialize(pool: nil, config: nil)
|
9
|
+
@redis_client = Client.new(pool: pool, config: config)
|
10
|
+
end
|
11
|
+
|
12
|
+
def push(item)
|
13
|
+
# pre-allocate the JID so we can return it immediately and
|
14
|
+
# save it to the database as part of the transaction.
|
15
|
+
item["jid"] ||= SecureRandom.hex(12)
|
16
|
+
AfterCommitEverywhere.after_commit { @redis_client.push(item) }
|
17
|
+
item["jid"]
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# We don't provide transactionality for push_bulk because we don't want
|
22
|
+
# to hold potentially hundreds of thousands of job records in memory due to
|
23
|
+
# a long running enqueue process.
|
24
|
+
def push_bulk(items)
|
25
|
+
@redis_client.push_bulk(items)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Use `Sidekiq.transactional_push!` in your sidekiq.rb initializer
|
32
|
+
module Sidekiq
|
33
|
+
def self.transactional_push!
|
34
|
+
begin
|
35
|
+
require "after_commit_everywhere"
|
36
|
+
rescue LoadError
|
37
|
+
raise %q(You need to add `gem "after_commit_everywhere"` to your Gemfile to use Sidekiq's transactional client)
|
38
|
+
end
|
39
|
+
|
40
|
+
Sidekiq.default_job_options["client_class"] = Sidekiq::TransactionAwareClient
|
41
|
+
Sidekiq::JobUtil::TRANSIENT_ATTRIBUTES << "client_class"
|
42
|
+
true
|
43
|
+
end
|
44
|
+
end
|
data/lib/sidekiq/version.rb
CHANGED
data/lib/sidekiq/web/action.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Sidekiq
|
4
4
|
class WebAction
|
5
|
-
RACK_SESSION =
|
5
|
+
RACK_SESSION = "rack.session"
|
6
6
|
|
7
7
|
attr_accessor :env, :block, :type
|
8
8
|
|
@@ -15,18 +15,18 @@ module Sidekiq
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def halt(res)
|
18
|
-
throw :halt, [res, {
|
18
|
+
throw :halt, [res, {Rack::CONTENT_TYPE => "text/plain"}, [res.to_s]]
|
19
19
|
end
|
20
20
|
|
21
21
|
def redirect(location)
|
22
|
-
throw :halt, [302, {
|
22
|
+
throw :halt, [302, {Web::LOCATION => "#{request.base_url}#{location}"}, []]
|
23
23
|
end
|
24
24
|
|
25
25
|
def params
|
26
|
-
indifferent_hash = Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
|
26
|
+
indifferent_hash = Hash.new { |hash, key| hash[key.to_s] if Symbol === key }
|
27
27
|
|
28
28
|
indifferent_hash.merge! request.params
|
29
|
-
route_params.each {|k,v| indifferent_hash[k.to_s] = v }
|
29
|
+
route_params.each { |k, v| indifferent_hash[k.to_s] = v }
|
30
30
|
|
31
31
|
indifferent_hash
|
32
32
|
end
|
@@ -40,10 +40,14 @@ module Sidekiq
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def erb(content, options = {})
|
43
|
-
if content.
|
43
|
+
if content.is_a? Symbol
|
44
44
|
unless respond_to?(:"_erb_#{content}")
|
45
45
|
src = ERB.new(File.read("#{Web.settings.views}/#{content}.erb")).src
|
46
|
-
WebAction.class_eval
|
46
|
+
WebAction.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
47
|
+
def _erb_#{content}
|
48
|
+
#{src}
|
49
|
+
end
|
50
|
+
RUBY
|
47
51
|
end
|
48
52
|
end
|
49
53
|
|
@@ -64,22 +68,22 @@ module Sidekiq
|
|
64
68
|
end
|
65
69
|
|
66
70
|
def json(payload)
|
67
|
-
[200, {
|
71
|
+
[200, {Rack::CONTENT_TYPE => "application/json", Rack::CACHE_CONTROL => "private, no-store"}, [Sidekiq.dump_json(payload)]]
|
68
72
|
end
|
69
73
|
|
70
74
|
def initialize(env, block)
|
71
75
|
@_erb = false
|
72
76
|
@env = env
|
73
77
|
@block = block
|
74
|
-
|
78
|
+
@files ||= {}
|
75
79
|
end
|
76
80
|
|
77
81
|
private
|
78
82
|
|
79
83
|
def _erb(file, locals)
|
80
|
-
locals
|
84
|
+
locals&.each { |k, v| define_singleton_method(k) { v } unless singleton_methods.include? k }
|
81
85
|
|
82
|
-
if file.
|
86
|
+
if file.is_a?(String)
|
83
87
|
ERB.new(file).result(binding)
|
84
88
|
else
|
85
89
|
send(:"_erb_#{file}")
|