sidekiq 0.10.0 → 7.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (234) hide show
  1. checksums.yaml +7 -0
  2. data/Changes.md +2047 -0
  3. data/LICENSE.txt +9 -0
  4. data/README.md +73 -27
  5. data/bin/sidekiq +25 -9
  6. data/bin/sidekiqload +247 -0
  7. data/bin/sidekiqmon +11 -0
  8. data/lib/generators/sidekiq/job_generator.rb +57 -0
  9. data/lib/generators/sidekiq/templates/job.rb.erb +9 -0
  10. data/lib/generators/sidekiq/templates/job_spec.rb.erb +6 -0
  11. data/lib/generators/sidekiq/templates/job_test.rb.erb +8 -0
  12. data/lib/sidekiq/api.rb +1145 -0
  13. data/lib/sidekiq/capsule.rb +127 -0
  14. data/lib/sidekiq/cli.rb +348 -109
  15. data/lib/sidekiq/client.rb +241 -41
  16. data/lib/sidekiq/component.rb +68 -0
  17. data/lib/sidekiq/config.rb +287 -0
  18. data/lib/sidekiq/deploy.rb +62 -0
  19. data/lib/sidekiq/embedded.rb +61 -0
  20. data/lib/sidekiq/fetch.rb +88 -0
  21. data/lib/sidekiq/job.rb +374 -0
  22. data/lib/sidekiq/job_logger.rb +51 -0
  23. data/lib/sidekiq/job_retry.rb +300 -0
  24. data/lib/sidekiq/job_util.rb +107 -0
  25. data/lib/sidekiq/launcher.rb +271 -0
  26. data/lib/sidekiq/logger.rb +131 -0
  27. data/lib/sidekiq/manager.rb +96 -103
  28. data/lib/sidekiq/metrics/query.rb +153 -0
  29. data/lib/sidekiq/metrics/shared.rb +95 -0
  30. data/lib/sidekiq/metrics/tracking.rb +136 -0
  31. data/lib/sidekiq/middleware/chain.rb +149 -38
  32. data/lib/sidekiq/middleware/current_attributes.rb +95 -0
  33. data/lib/sidekiq/middleware/i18n.rb +42 -0
  34. data/lib/sidekiq/middleware/modules.rb +21 -0
  35. data/lib/sidekiq/monitor.rb +146 -0
  36. data/lib/sidekiq/paginator.rb +55 -0
  37. data/lib/sidekiq/processor.rb +246 -61
  38. data/lib/sidekiq/rails.rb +60 -13
  39. data/lib/sidekiq/redis_client_adapter.rb +95 -0
  40. data/lib/sidekiq/redis_connection.rb +68 -15
  41. data/lib/sidekiq/ring_buffer.rb +29 -0
  42. data/lib/sidekiq/scheduled.rb +236 -0
  43. data/lib/sidekiq/sd_notify.rb +149 -0
  44. data/lib/sidekiq/systemd.rb +24 -0
  45. data/lib/sidekiq/testing/inline.rb +30 -0
  46. data/lib/sidekiq/testing.rb +304 -10
  47. data/lib/sidekiq/transaction_aware_client.rb +44 -0
  48. data/lib/sidekiq/version.rb +4 -1
  49. data/lib/sidekiq/web/action.rb +93 -0
  50. data/lib/sidekiq/web/application.rb +447 -0
  51. data/lib/sidekiq/web/csrf_protection.rb +180 -0
  52. data/lib/sidekiq/web/helpers.rb +370 -0
  53. data/lib/sidekiq/web/router.rb +104 -0
  54. data/lib/sidekiq/web.rb +143 -74
  55. data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
  56. data/lib/sidekiq.rb +120 -73
  57. data/sidekiq.gemspec +26 -23
  58. data/web/assets/images/apple-touch-icon.png +0 -0
  59. data/web/assets/images/favicon.ico +0 -0
  60. data/web/assets/images/logo.png +0 -0
  61. data/web/assets/images/status.png +0 -0
  62. data/web/assets/javascripts/application.js +162 -3
  63. data/web/assets/javascripts/base-charts.js +106 -0
  64. data/web/assets/javascripts/chart.min.js +13 -0
  65. data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
  66. data/web/assets/javascripts/dashboard-charts.js +168 -0
  67. data/web/assets/javascripts/dashboard.js +59 -0
  68. data/web/assets/javascripts/metrics.js +264 -0
  69. data/web/assets/stylesheets/application-dark.css +147 -0
  70. data/web/assets/stylesheets/application-rtl.css +153 -0
  71. data/web/assets/stylesheets/application.css +720 -7
  72. data/web/assets/stylesheets/bootstrap-rtl.min.css +9 -0
  73. data/web/assets/stylesheets/bootstrap.css +5 -0
  74. data/web/locales/ar.yml +87 -0
  75. data/web/locales/cs.yml +78 -0
  76. data/web/locales/da.yml +75 -0
  77. data/web/locales/de.yml +81 -0
  78. data/web/locales/el.yml +87 -0
  79. data/web/locales/en.yml +101 -0
  80. data/web/locales/es.yml +86 -0
  81. data/web/locales/fa.yml +80 -0
  82. data/web/locales/fr.yml +99 -0
  83. data/web/locales/gd.yml +99 -0
  84. data/web/locales/he.yml +80 -0
  85. data/web/locales/hi.yml +75 -0
  86. data/web/locales/it.yml +69 -0
  87. data/web/locales/ja.yml +91 -0
  88. data/web/locales/ko.yml +68 -0
  89. data/web/locales/lt.yml +83 -0
  90. data/web/locales/nb.yml +77 -0
  91. data/web/locales/nl.yml +68 -0
  92. data/web/locales/pl.yml +59 -0
  93. data/web/locales/pt-br.yml +96 -0
  94. data/web/locales/pt.yml +67 -0
  95. data/web/locales/ru.yml +83 -0
  96. data/web/locales/sv.yml +68 -0
  97. data/web/locales/ta.yml +75 -0
  98. data/web/locales/uk.yml +77 -0
  99. data/web/locales/ur.yml +80 -0
  100. data/web/locales/vi.yml +83 -0
  101. data/web/locales/zh-cn.yml +95 -0
  102. data/web/locales/zh-tw.yml +102 -0
  103. data/web/views/_footer.erb +23 -0
  104. data/web/views/_job_info.erb +105 -0
  105. data/web/views/_metrics_period_select.erb +12 -0
  106. data/web/views/_nav.erb +52 -0
  107. data/web/views/_paging.erb +25 -0
  108. data/web/views/_poll_link.erb +4 -0
  109. data/web/views/_status.erb +4 -0
  110. data/web/views/_summary.erb +40 -0
  111. data/web/views/busy.erb +148 -0
  112. data/web/views/dashboard.erb +115 -0
  113. data/web/views/dead.erb +34 -0
  114. data/web/views/filtering.erb +7 -0
  115. data/web/views/layout.erb +42 -0
  116. data/web/views/metrics.erb +82 -0
  117. data/web/views/metrics_for_job.erb +68 -0
  118. data/web/views/morgue.erb +74 -0
  119. data/web/views/queue.erb +55 -0
  120. data/web/views/queues.erb +40 -0
  121. data/web/views/retries.erb +79 -0
  122. data/web/views/retry.erb +34 -0
  123. data/web/views/scheduled.erb +56 -0
  124. data/web/views/scheduled_job_info.erb +8 -0
  125. metadata +159 -237
  126. data/.gitignore +0 -6
  127. data/.rvmrc +0 -4
  128. data/COMM-LICENSE +0 -75
  129. data/Gemfile +0 -10
  130. data/LICENSE +0 -22
  131. data/Rakefile +0 -9
  132. data/TODO.md +0 -1
  133. data/bin/client +0 -7
  134. data/bin/sidekiqctl +0 -43
  135. data/config.ru +0 -8
  136. data/examples/chef/cookbooks/sidekiq/README.rdoc +0 -11
  137. data/examples/chef/cookbooks/sidekiq/recipes/default.rb +0 -55
  138. data/examples/chef/cookbooks/sidekiq/templates/default/monitrc.conf.erb +0 -8
  139. data/examples/chef/cookbooks/sidekiq/templates/default/sidekiq.erb +0 -219
  140. data/examples/chef/cookbooks/sidekiq/templates/default/sidekiq.yml.erb +0 -22
  141. data/examples/config.yml +0 -9
  142. data/examples/monitrc.conf +0 -6
  143. data/examples/por.rb +0 -27
  144. data/examples/scheduling.rb +0 -37
  145. data/examples/sinkiq.rb +0 -57
  146. data/examples/web-ui.png +0 -0
  147. data/lib/sidekiq/capistrano.rb +0 -32
  148. data/lib/sidekiq/extensions/action_mailer.rb +0 -26
  149. data/lib/sidekiq/extensions/active_record.rb +0 -27
  150. data/lib/sidekiq/extensions/generic_proxy.rb +0 -21
  151. data/lib/sidekiq/middleware/client/unique_jobs.rb +0 -32
  152. data/lib/sidekiq/middleware/server/active_record.rb +0 -13
  153. data/lib/sidekiq/middleware/server/exception_handler.rb +0 -38
  154. data/lib/sidekiq/middleware/server/failure_jobs.rb +0 -24
  155. data/lib/sidekiq/middleware/server/logging.rb +0 -27
  156. data/lib/sidekiq/middleware/server/retry_jobs.rb +0 -59
  157. data/lib/sidekiq/middleware/server/unique_jobs.rb +0 -15
  158. data/lib/sidekiq/retry.rb +0 -57
  159. data/lib/sidekiq/util.rb +0 -61
  160. data/lib/sidekiq/worker.rb +0 -37
  161. data/myapp/.gitignore +0 -15
  162. data/myapp/Capfile +0 -5
  163. data/myapp/Gemfile +0 -19
  164. data/myapp/Gemfile.lock +0 -143
  165. data/myapp/Rakefile +0 -7
  166. data/myapp/app/controllers/application_controller.rb +0 -3
  167. data/myapp/app/controllers/work_controller.rb +0 -38
  168. data/myapp/app/helpers/application_helper.rb +0 -2
  169. data/myapp/app/mailers/.gitkeep +0 -0
  170. data/myapp/app/mailers/user_mailer.rb +0 -9
  171. data/myapp/app/models/.gitkeep +0 -0
  172. data/myapp/app/models/post.rb +0 -5
  173. data/myapp/app/views/layouts/application.html.erb +0 -14
  174. data/myapp/app/views/user_mailer/greetings.html.erb +0 -3
  175. data/myapp/app/views/work/index.html.erb +0 -1
  176. data/myapp/app/workers/hard_worker.rb +0 -9
  177. data/myapp/config/application.rb +0 -59
  178. data/myapp/config/boot.rb +0 -6
  179. data/myapp/config/database.yml +0 -25
  180. data/myapp/config/deploy.rb +0 -15
  181. data/myapp/config/environment.rb +0 -5
  182. data/myapp/config/environments/development.rb +0 -38
  183. data/myapp/config/environments/production.rb +0 -67
  184. data/myapp/config/environments/test.rb +0 -37
  185. data/myapp/config/initializers/backtrace_silencers.rb +0 -7
  186. data/myapp/config/initializers/inflections.rb +0 -15
  187. data/myapp/config/initializers/mime_types.rb +0 -5
  188. data/myapp/config/initializers/secret_token.rb +0 -7
  189. data/myapp/config/initializers/session_store.rb +0 -8
  190. data/myapp/config/initializers/sidekiq.rb +0 -6
  191. data/myapp/config/initializers/wrap_parameters.rb +0 -14
  192. data/myapp/config/locales/en.yml +0 -5
  193. data/myapp/config/routes.rb +0 -10
  194. data/myapp/config.ru +0 -4
  195. data/myapp/db/migrate/20120123214055_create_posts.rb +0 -10
  196. data/myapp/db/seeds.rb +0 -7
  197. data/myapp/lib/assets/.gitkeep +0 -0
  198. data/myapp/lib/tasks/.gitkeep +0 -0
  199. data/myapp/log/.gitkeep +0 -0
  200. data/myapp/script/rails +0 -6
  201. data/test/config.yml +0 -9
  202. data/test/fake_env.rb +0 -0
  203. data/test/helper.rb +0 -15
  204. data/test/test_cli.rb +0 -168
  205. data/test/test_client.rb +0 -105
  206. data/test/test_extensions.rb +0 -68
  207. data/test/test_manager.rb +0 -43
  208. data/test/test_middleware.rb +0 -92
  209. data/test/test_processor.rb +0 -32
  210. data/test/test_retry.rb +0 -83
  211. data/test/test_stats.rb +0 -78
  212. data/test/test_testing.rb +0 -65
  213. data/test/test_web.rb +0 -61
  214. data/web/assets/images/bootstrap/glyphicons-halflings-white.png +0 -0
  215. data/web/assets/images/bootstrap/glyphicons-halflings.png +0 -0
  216. data/web/assets/javascripts/vendor/bootstrap/bootstrap-alert.js +0 -91
  217. data/web/assets/javascripts/vendor/bootstrap/bootstrap-button.js +0 -98
  218. data/web/assets/javascripts/vendor/bootstrap/bootstrap-carousel.js +0 -154
  219. data/web/assets/javascripts/vendor/bootstrap/bootstrap-collapse.js +0 -136
  220. data/web/assets/javascripts/vendor/bootstrap/bootstrap-dropdown.js +0 -92
  221. data/web/assets/javascripts/vendor/bootstrap/bootstrap-modal.js +0 -210
  222. data/web/assets/javascripts/vendor/bootstrap/bootstrap-popover.js +0 -95
  223. data/web/assets/javascripts/vendor/bootstrap/bootstrap-scrollspy.js +0 -125
  224. data/web/assets/javascripts/vendor/bootstrap/bootstrap-tab.js +0 -130
  225. data/web/assets/javascripts/vendor/bootstrap/bootstrap-tooltip.js +0 -270
  226. data/web/assets/javascripts/vendor/bootstrap/bootstrap-transition.js +0 -51
  227. data/web/assets/javascripts/vendor/bootstrap/bootstrap-typeahead.js +0 -271
  228. data/web/assets/javascripts/vendor/bootstrap.js +0 -12
  229. data/web/assets/javascripts/vendor/jquery.js +0 -9266
  230. data/web/assets/stylesheets/vendor/bootstrap-responsive.css +0 -567
  231. data/web/assets/stylesheets/vendor/bootstrap.css +0 -3365
  232. data/web/views/index.slim +0 -62
  233. data/web/views/layout.slim +0 -24
  234. data/web/views/queue.slim +0 -11
@@ -1,6 +1,209 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "securerandom"
4
+ require "sidekiq"
5
+
1
6
  module Sidekiq
2
- module Worker
7
+ class Testing
8
+ class << self
9
+ attr_accessor :__global_test_mode
10
+
11
+ # Calling without a block sets the global test mode, affecting
12
+ # all threads. Calling with a block only affects the current Thread.
13
+ def __set_test_mode(mode)
14
+ if block_given?
15
+ begin
16
+ self.__local_test_mode = mode
17
+ yield
18
+ ensure
19
+ self.__local_test_mode = nil
20
+ end
21
+ else
22
+ self.__global_test_mode = mode
23
+ end
24
+ end
25
+
26
+ def __test_mode
27
+ __local_test_mode || __global_test_mode
28
+ end
29
+
30
+ def __local_test_mode
31
+ Thread.current[:__sidekiq_test_mode]
32
+ end
33
+
34
+ def __local_test_mode=(value)
35
+ Thread.current[:__sidekiq_test_mode] = value
36
+ end
37
+
38
+ def disable!(&block)
39
+ __set_test_mode(:disable, &block)
40
+ end
41
+
42
+ def fake!(&block)
43
+ __set_test_mode(:fake, &block)
44
+ end
45
+
46
+ def inline!(&block)
47
+ __set_test_mode(:inline, &block)
48
+ end
49
+
50
+ def enabled?
51
+ __test_mode != :disable
52
+ end
53
+
54
+ def disabled?
55
+ __test_mode == :disable
56
+ end
3
57
 
58
+ def fake?
59
+ __test_mode == :fake
60
+ end
61
+
62
+ def inline?
63
+ __test_mode == :inline
64
+ end
65
+
66
+ def server_middleware
67
+ @server_chain ||= Middleware::Chain.new(Sidekiq.default_configuration)
68
+ yield @server_chain if block_given?
69
+ @server_chain
70
+ end
71
+ end
72
+ end
73
+
74
+ # Default to fake testing to keep old behavior
75
+ Sidekiq::Testing.fake!
76
+
77
+ class EmptyQueueError < RuntimeError; end
78
+
79
+ module TestingClient
80
+ def atomic_push(conn, payloads)
81
+ if Sidekiq::Testing.fake?
82
+ payloads.each do |job|
83
+ job = Sidekiq.load_json(Sidekiq.dump_json(job))
84
+ job["enqueued_at"] = Time.now.to_f unless job["at"]
85
+ Queues.push(job["queue"], job["class"], job)
86
+ end
87
+ true
88
+ elsif Sidekiq::Testing.inline?
89
+ payloads.each do |job|
90
+ klass = Object.const_get(job["class"])
91
+ job["id"] ||= SecureRandom.hex(12)
92
+ job_hash = Sidekiq.load_json(Sidekiq.dump_json(job))
93
+ klass.process_job(job_hash)
94
+ end
95
+ true
96
+ else
97
+ super
98
+ end
99
+ end
100
+ end
101
+
102
+ Sidekiq::Client.prepend TestingClient
103
+
104
+ module Queues
105
+ ##
106
+ # The Queues class is only for testing the fake queue implementation.
107
+ # There are 2 data structures involved in tandem. This is due to the
108
+ # Rspec syntax of change(HardJob.jobs, :size). It keeps a reference
109
+ # to the array. Because the array was dervied from a filter of the total
110
+ # jobs enqueued, it appeared as though the array didn't change.
111
+ #
112
+ # To solve this, we'll keep 2 hashes containing the jobs. One with keys based
113
+ # on the queue, and another with keys of the job type, so the array for
114
+ # HardJob.jobs is a straight reference to a real array.
115
+ #
116
+ # Queue-based hash:
117
+ #
118
+ # {
119
+ # "default"=>[
120
+ # {
121
+ # "class"=>"TestTesting::HardJob",
122
+ # "args"=>[1, 2],
123
+ # "retry"=>true,
124
+ # "queue"=>"default",
125
+ # "jid"=>"abc5b065c5c4b27fc1102833",
126
+ # "created_at"=>1447445554.419934
127
+ # }
128
+ # ]
129
+ # }
130
+ #
131
+ # Job-based hash:
132
+ #
133
+ # {
134
+ # "TestTesting::HardJob"=>[
135
+ # {
136
+ # "class"=>"TestTesting::HardJob",
137
+ # "args"=>[1, 2],
138
+ # "retry"=>true,
139
+ # "queue"=>"default",
140
+ # "jid"=>"abc5b065c5c4b27fc1102833",
141
+ # "created_at"=>1447445554.419934
142
+ # }
143
+ # ]
144
+ # }
145
+ #
146
+ # Example:
147
+ #
148
+ # require 'sidekiq/testing'
149
+ #
150
+ # assert_equal 0, Sidekiq::Queues["default"].size
151
+ # HardJob.perform_async(:something)
152
+ # assert_equal 1, Sidekiq::Queues["default"].size
153
+ # assert_equal :something, Sidekiq::Queues["default"].first['args'][0]
154
+ #
155
+ # You can also clear all jobs:
156
+ #
157
+ # assert_equal 0, Sidekiq::Queues["default"].size
158
+ # HardJob.perform_async(:something)
159
+ # Sidekiq::Queues.clear_all
160
+ # assert_equal 0, Sidekiq::Queues["default"].size
161
+ #
162
+ # This can be useful to make sure jobs don't linger between tests:
163
+ #
164
+ # RSpec.configure do |config|
165
+ # config.before(:each) do
166
+ # Sidekiq::Queues.clear_all
167
+ # end
168
+ # end
169
+ #
170
+ class << self
171
+ def [](queue)
172
+ jobs_by_queue[queue]
173
+ end
174
+
175
+ def push(queue, klass, job)
176
+ jobs_by_queue[queue] << job
177
+ jobs_by_class[klass] << job
178
+ end
179
+
180
+ def jobs_by_queue
181
+ @jobs_by_queue ||= Hash.new { |hash, key| hash[key] = [] }
182
+ end
183
+
184
+ def jobs_by_class
185
+ @jobs_by_class ||= Hash.new { |hash, key| hash[key] = [] }
186
+ end
187
+ alias_method :jobs_by_worker, :jobs_by_class
188
+
189
+ def delete_for(jid, queue, klass)
190
+ jobs_by_queue[queue.to_s].delete_if { |job| job["jid"] == jid }
191
+ jobs_by_class[klass].delete_if { |job| job["jid"] == jid }
192
+ end
193
+
194
+ def clear_for(queue, klass)
195
+ jobs_by_queue[queue.to_s].clear
196
+ jobs_by_class[klass].clear
197
+ end
198
+
199
+ def clear_all
200
+ jobs_by_queue.clear
201
+ jobs_by_class.clear
202
+ end
203
+ end
204
+ end
205
+
206
+ module Job
4
207
  ##
5
208
  # The Sidekiq testing infrastructure overrides perform_async
6
209
  # so that it does not actually touch the network. Instead it
@@ -14,21 +217,112 @@ module Sidekiq
14
217
  #
15
218
  # require 'sidekiq/testing'
16
219
  #
17
- # assert_equal 0, HardWorker.jobs.size
18
- # HardWorker.perform_async(:something)
19
- # assert_equal 1, HardWorker.jobs.size
20
- # assert_equal :something, HardWorker.jobs[0]['args'][0]
220
+ # assert_equal 0, HardJob.jobs.size
221
+ # HardJob.perform_async(:something)
222
+ # assert_equal 1, HardJob.jobs.size
223
+ # assert_equal :something, HardJob.jobs[0]['args'][0]
224
+ #
225
+ # You can also clear and drain all job types:
226
+ #
227
+ # Sidekiq::Job.clear_all # or .drain_all
228
+ #
229
+ # This can be useful to make sure jobs don't linger between tests:
230
+ #
231
+ # RSpec.configure do |config|
232
+ # config.before(:each) do
233
+ # Sidekiq::Job.clear_all
234
+ # end
235
+ # end
236
+ #
237
+ # or for acceptance testing, i.e. with cucumber:
238
+ #
239
+ # AfterStep do
240
+ # Sidekiq::Job.drain_all
241
+ # end
242
+ #
243
+ # When I sign up as "foo@example.com"
244
+ # Then I should receive a welcome email to "foo@example.com"
21
245
  #
22
246
  module ClassMethods
23
- alias_method :perform_async_old, :perform_async
24
- def perform_async(*args)
25
- jobs << { 'class' => self.name, 'args' => args }
26
- true
247
+ # Queue for this worker
248
+ def queue
249
+ get_sidekiq_options["queue"]
27
250
  end
28
251
 
252
+ # Jobs queued for this worker
29
253
  def jobs
30
- @pushed ||= []
254
+ Queues.jobs_by_class[to_s]
255
+ end
256
+
257
+ # Clear all jobs for this worker
258
+ def clear
259
+ Queues.clear_for(queue, to_s)
260
+ end
261
+
262
+ # Drain and run all jobs for this worker
263
+ def drain
264
+ while jobs.any?
265
+ next_job = jobs.first
266
+ Queues.delete_for(next_job["jid"], next_job["queue"], to_s)
267
+ process_job(next_job)
268
+ end
269
+ end
270
+
271
+ # Pop out a single job and perform it
272
+ def perform_one
273
+ raise(EmptyQueueError, "perform_one called with empty job queue") if jobs.empty?
274
+ next_job = jobs.first
275
+ Queues.delete_for(next_job["jid"], queue, to_s)
276
+ process_job(next_job)
277
+ end
278
+
279
+ def process_job(job)
280
+ inst = new
281
+ inst.jid = job["jid"]
282
+ inst.bid = job["bid"] if inst.respond_to?(:bid=)
283
+ Sidekiq::Testing.server_middleware.invoke(inst, job, job["queue"]) do
284
+ execute_job(inst, job["args"])
285
+ end
286
+ end
287
+
288
+ def execute_job(worker, args)
289
+ worker.perform(*args)
290
+ end
291
+ end
292
+
293
+ class << self
294
+ def jobs # :nodoc:
295
+ Queues.jobs_by_queue.values.flatten
296
+ end
297
+
298
+ # Clear all queued jobs
299
+ def clear_all
300
+ Queues.clear_all
301
+ end
302
+
303
+ # Drain (execute) all queued jobs
304
+ def drain_all
305
+ while jobs.any?
306
+ job_classes = jobs.map { |job| job["class"] }.uniq
307
+
308
+ job_classes.each do |job_class|
309
+ Object.const_get(job_class).drain
310
+ end
311
+ end
31
312
  end
32
313
  end
33
314
  end
315
+
316
+ module TestingExtensions
317
+ def jobs_for(klass)
318
+ jobs.select do |job|
319
+ marshalled = job["args"][0]
320
+ marshalled.index(klass.to_s) && YAML.safe_load(marshalled)[0] == klass
321
+ end
322
+ end
323
+ end
324
+ end
325
+
326
+ if defined?(::Rails) && Rails.respond_to?(:env) && !Rails.env.test? && !$TESTING
327
+ warn("⛔️ WARNING: Sidekiq testing API enabled, but this is not the test environment. Your jobs will not go to Redis.", uplevel: 1)
34
328
  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
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Sidekiq
2
- VERSION = "0.10.0"
4
+ VERSION = "7.1.6"
5
+ MAJOR = 7
3
6
  end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sidekiq
4
+ class WebAction
5
+ RACK_SESSION = "rack.session"
6
+
7
+ attr_accessor :env, :block, :type
8
+
9
+ def settings
10
+ Web.settings
11
+ end
12
+
13
+ def request
14
+ @request ||= ::Rack::Request.new(env)
15
+ end
16
+
17
+ def halt(res)
18
+ throw :halt, [res, {Rack::CONTENT_TYPE => "text/plain"}, [res.to_s]]
19
+ end
20
+
21
+ def redirect(location)
22
+ throw :halt, [302, {Web::LOCATION => "#{request.base_url}#{location}"}, []]
23
+ end
24
+
25
+ def params
26
+ indifferent_hash = Hash.new { |hash, key| hash[key.to_s] if Symbol === key }
27
+
28
+ indifferent_hash.merge! request.params
29
+ route_params.each { |k, v| indifferent_hash[k.to_s] = v }
30
+
31
+ indifferent_hash
32
+ end
33
+
34
+ def route_params
35
+ env[WebRouter::ROUTE_PARAMS]
36
+ end
37
+
38
+ def session
39
+ env[RACK_SESSION]
40
+ end
41
+
42
+ def erb(content, options = {})
43
+ if content.is_a? Symbol
44
+ unless respond_to?(:"_erb_#{content}")
45
+ src = ERB.new(File.read("#{Web.settings.views}/#{content}.erb")).src
46
+ WebAction.class_eval <<-RUBY, __FILE__, __LINE__ + 1
47
+ def _erb_#{content}
48
+ #{src}
49
+ end
50
+ RUBY
51
+ end
52
+ end
53
+
54
+ if @_erb
55
+ _erb(content, options[:locals])
56
+ else
57
+ @_erb = true
58
+ content = _erb(content, options[:locals])
59
+
60
+ _render { content }
61
+ end
62
+ end
63
+
64
+ def render(engine, content, options = {})
65
+ raise "Only erb templates are supported" if engine != :erb
66
+
67
+ erb(content, options)
68
+ end
69
+
70
+ def json(payload)
71
+ [200, {Rack::CONTENT_TYPE => "application/json", Rack::CACHE_CONTROL => "private, no-store"}, [Sidekiq.dump_json(payload)]]
72
+ end
73
+
74
+ def initialize(env, block)
75
+ @_erb = false
76
+ @env = env
77
+ @block = block
78
+ @files ||= {}
79
+ end
80
+
81
+ private
82
+
83
+ def _erb(file, locals)
84
+ locals&.each { |k, v| define_singleton_method(k) { v } unless singleton_methods.include? k }
85
+
86
+ if file.is_a?(String)
87
+ ERB.new(file).result(binding)
88
+ else
89
+ send(:"_erb_#{file}")
90
+ end
91
+ end
92
+ end
93
+ end