sidekiq 5.2.2 → 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.

Files changed (149) hide show
  1. checksums.yaml +5 -5
  2. data/Changes.md +657 -8
  3. data/LICENSE.txt +9 -0
  4. data/README.md +47 -50
  5. data/bin/sidekiq +22 -3
  6. data/bin/sidekiqload +213 -115
  7. data/bin/sidekiqmon +11 -0
  8. data/lib/generators/sidekiq/job_generator.rb +57 -0
  9. data/lib/generators/sidekiq/templates/{worker.rb.erb → job.rb.erb} +2 -2
  10. data/lib/generators/sidekiq/templates/{worker_spec.rb.erb → job_spec.rb.erb} +1 -1
  11. data/lib/generators/sidekiq/templates/{worker_test.rb.erb → job_test.rb.erb} +1 -1
  12. data/lib/sidekiq/api.rb +558 -353
  13. data/lib/sidekiq/capsule.rb +127 -0
  14. data/lib/sidekiq/cli.rb +238 -260
  15. data/lib/sidekiq/client.rb +127 -102
  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 +49 -42
  21. data/lib/sidekiq/job.rb +374 -0
  22. data/lib/sidekiq/job_logger.rb +35 -9
  23. data/lib/sidekiq/job_retry.rb +162 -102
  24. data/lib/sidekiq/job_util.rb +107 -0
  25. data/lib/sidekiq/launcher.rb +203 -105
  26. data/lib/sidekiq/logger.rb +131 -0
  27. data/lib/sidekiq/manager.rb +43 -46
  28. data/lib/sidekiq/metrics/query.rb +155 -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 +113 -56
  32. data/lib/sidekiq/middleware/current_attributes.rb +95 -0
  33. data/lib/sidekiq/middleware/i18n.rb +7 -7
  34. data/lib/sidekiq/middleware/modules.rb +21 -0
  35. data/lib/sidekiq/monitor.rb +146 -0
  36. data/lib/sidekiq/paginator.rb +28 -16
  37. data/lib/sidekiq/processor.rb +127 -118
  38. data/lib/sidekiq/rails.rb +50 -39
  39. data/lib/sidekiq/redis_client_adapter.rb +111 -0
  40. data/lib/sidekiq/redis_connection.rb +40 -89
  41. data/lib/sidekiq/ring_buffer.rb +29 -0
  42. data/lib/sidekiq/scheduled.rb +111 -49
  43. data/lib/sidekiq/sd_notify.rb +149 -0
  44. data/lib/sidekiq/systemd.rb +24 -0
  45. data/lib/sidekiq/testing/inline.rb +6 -5
  46. data/lib/sidekiq/testing.rb +90 -89
  47. data/lib/sidekiq/transaction_aware_client.rb +44 -0
  48. data/lib/sidekiq/version.rb +3 -1
  49. data/lib/sidekiq/web/action.rb +15 -11
  50. data/lib/sidekiq/web/application.rb +189 -79
  51. data/lib/sidekiq/web/csrf_protection.rb +180 -0
  52. data/lib/sidekiq/web/helpers.rb +160 -114
  53. data/lib/sidekiq/web/router.rb +23 -19
  54. data/lib/sidekiq/web.rb +68 -107
  55. data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
  56. data/lib/sidekiq.rb +94 -182
  57. data/sidekiq.gemspec +25 -18
  58. data/web/assets/images/apple-touch-icon.png +0 -0
  59. data/web/assets/javascripts/application.js +146 -61
  60. data/web/assets/javascripts/base-charts.js +106 -0
  61. data/web/assets/javascripts/chart.min.js +13 -0
  62. data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
  63. data/web/assets/javascripts/dashboard-charts.js +182 -0
  64. data/web/assets/javascripts/dashboard.js +35 -283
  65. data/web/assets/javascripts/metrics.js +298 -0
  66. data/web/assets/stylesheets/application-dark.css +147 -0
  67. data/web/assets/stylesheets/application-rtl.css +2 -95
  68. data/web/assets/stylesheets/application.css +143 -521
  69. data/web/assets/stylesheets/bootstrap.css +1 -1
  70. data/web/locales/ar.yml +71 -65
  71. data/web/locales/cs.yml +62 -62
  72. data/web/locales/da.yml +60 -53
  73. data/web/locales/de.yml +65 -53
  74. data/web/locales/el.yml +43 -24
  75. data/web/locales/en.yml +86 -66
  76. data/web/locales/es.yml +70 -54
  77. data/web/locales/fa.yml +65 -65
  78. data/web/locales/fr.yml +83 -62
  79. data/web/locales/gd.yml +99 -0
  80. data/web/locales/he.yml +65 -64
  81. data/web/locales/hi.yml +59 -59
  82. data/web/locales/it.yml +53 -53
  83. data/web/locales/ja.yml +75 -64
  84. data/web/locales/ko.yml +52 -52
  85. data/web/locales/lt.yml +83 -0
  86. data/web/locales/nb.yml +61 -61
  87. data/web/locales/nl.yml +52 -52
  88. data/web/locales/pl.yml +45 -45
  89. data/web/locales/pt-br.yml +83 -55
  90. data/web/locales/pt.yml +51 -51
  91. data/web/locales/ru.yml +68 -63
  92. data/web/locales/sv.yml +53 -53
  93. data/web/locales/ta.yml +60 -60
  94. data/web/locales/uk.yml +62 -61
  95. data/web/locales/ur.yml +64 -64
  96. data/web/locales/vi.yml +83 -0
  97. data/web/locales/zh-cn.yml +43 -16
  98. data/web/locales/zh-tw.yml +42 -8
  99. data/web/views/_footer.erb +6 -3
  100. data/web/views/_job_info.erb +21 -4
  101. data/web/views/_metrics_period_select.erb +12 -0
  102. data/web/views/_nav.erb +4 -18
  103. data/web/views/_paging.erb +2 -0
  104. data/web/views/_poll_link.erb +3 -6
  105. data/web/views/_summary.erb +7 -7
  106. data/web/views/busy.erb +77 -27
  107. data/web/views/dashboard.erb +48 -18
  108. data/web/views/dead.erb +3 -3
  109. data/web/views/filtering.erb +7 -0
  110. data/web/views/layout.erb +3 -1
  111. data/web/views/metrics.erb +91 -0
  112. data/web/views/metrics_for_job.erb +59 -0
  113. data/web/views/morgue.erb +14 -15
  114. data/web/views/queue.erb +33 -24
  115. data/web/views/queues.erb +19 -5
  116. data/web/views/retries.erb +16 -17
  117. data/web/views/retry.erb +3 -3
  118. data/web/views/scheduled.erb +17 -15
  119. metadata +80 -65
  120. data/.github/contributing.md +0 -32
  121. data/.github/issue_template.md +0 -11
  122. data/.gitignore +0 -13
  123. data/.travis.yml +0 -14
  124. data/3.0-Upgrade.md +0 -70
  125. data/4.0-Upgrade.md +0 -53
  126. data/5.0-Upgrade.md +0 -56
  127. data/COMM-LICENSE +0 -95
  128. data/Ent-Changes.md +0 -221
  129. data/Gemfile +0 -14
  130. data/LICENSE +0 -9
  131. data/Pro-2.0-Upgrade.md +0 -138
  132. data/Pro-3.0-Upgrade.md +0 -44
  133. data/Pro-4.0-Upgrade.md +0 -35
  134. data/Pro-Changes.md +0 -746
  135. data/Rakefile +0 -8
  136. data/bin/sidekiqctl +0 -99
  137. data/code_of_conduct.md +0 -50
  138. data/lib/generators/sidekiq/worker_generator.rb +0 -49
  139. data/lib/sidekiq/core_ext.rb +0 -1
  140. data/lib/sidekiq/delay.rb +0 -42
  141. data/lib/sidekiq/exception_handler.rb +0 -29
  142. data/lib/sidekiq/extensions/action_mailer.rb +0 -57
  143. data/lib/sidekiq/extensions/active_record.rb +0 -40
  144. data/lib/sidekiq/extensions/class_methods.rb +0 -40
  145. data/lib/sidekiq/extensions/generic_proxy.rb +0 -31
  146. data/lib/sidekiq/logging.rb +0 -122
  147. data/lib/sidekiq/middleware/server/active_record.rb +0 -23
  148. data/lib/sidekiq/util.rb +0 -66
  149. data/lib/sidekiq/worker.rb +0 -204
@@ -1,48 +1,81 @@
1
1
  # frozen_string_literal: true
2
- require 'uri'
3
- require 'set'
4
- require 'yaml'
5
- require 'cgi'
2
+
3
+ require "uri"
4
+ require "set"
5
+ require "yaml"
6
+ require "cgi"
6
7
 
7
8
  module Sidekiq
8
9
  # This is not a public API
9
10
  module WebHelpers
10
11
  def strings(lang)
11
- @@strings ||= {}
12
- @@strings[lang] ||= begin
13
- # Allow sidekiq-web extensions to add locale paths
14
- # so extensions can be localized
15
- settings.locales.each_with_object({}) do |path, global|
16
- find_locale_files(lang).each do |file|
17
- strs = YAML.load(File.open(file))
18
- global.merge!(strs[lang])
19
- end
12
+ @strings ||= {}
13
+
14
+ # Allow sidekiq-web extensions to add locale paths
15
+ # so extensions can be localized
16
+ @strings[lang] ||= settings.locales.each_with_object({}) do |path, global|
17
+ find_locale_files(lang).each do |file|
18
+ strs = YAML.safe_load(File.read(file))
19
+ global.merge!(strs[lang])
20
20
  end
21
21
  end
22
22
  end
23
23
 
24
+ def to_json(x)
25
+ Sidekiq.dump_json(x)
26
+ end
27
+
28
+ def singularize(str, count)
29
+ if count == 1 && str.respond_to?(:singularize) # rails
30
+ str.singularize
31
+ else
32
+ str
33
+ end
34
+ end
35
+
24
36
  def clear_caches
25
- @@strings = nil
26
- @@locale_files = nil
27
- @@available_locales = nil
37
+ @strings = nil
38
+ @locale_files = nil
39
+ @available_locales = nil
28
40
  end
29
41
 
30
42
  def locale_files
31
- @@locale_files ||= settings.locales.flat_map do |path|
43
+ @locale_files ||= settings.locales.flat_map { |path|
32
44
  Dir["#{path}/*.yml"]
33
- end
45
+ }
34
46
  end
35
47
 
36
48
  def available_locales
37
- @@available_locales ||= locale_files.map { |path| File.basename(path, '.yml') }.uniq
49
+ @available_locales ||= locale_files.map { |path| File.basename(path, ".yml") }.uniq
38
50
  end
39
51
 
40
52
  def find_locale_files(lang)
41
53
  locale_files.select { |file| file =~ /\/#{lang}\.yml$/ }
42
54
  end
43
55
 
44
- # This is a hook for a Sidekiq Pro feature. Please don't touch.
45
- def filtering(*)
56
+ def search(jobset, substr)
57
+ resultset = jobset.scan(substr).to_a
58
+ @current_page = 1
59
+ @count = @total_size = resultset.size
60
+ resultset
61
+ end
62
+
63
+ def filtering(which)
64
+ erb(:filtering, locals: {which: which})
65
+ end
66
+
67
+ def filter_link(jid, within = "retries")
68
+ if within.nil?
69
+ ::Rack::Utils.escape_html(jid)
70
+ else
71
+ "<a href='#{root_path}filter/#{within}?substr=#{jid}'>#{::Rack::Utils.escape_html(jid)}</a>"
72
+ end
73
+ end
74
+
75
+ def display_tags(job, within = "retries")
76
+ job.tags.map { |tag|
77
+ "<span class='label label-info jobtag'>#{filter_link(tag, within)}</span>"
78
+ }.join(" ")
46
79
  end
47
80
 
48
81
  # This view helper provide ability display you html code in
@@ -62,33 +95,25 @@ module Sidekiq
62
95
  @head_html.join if defined?(@head_html)
63
96
  end
64
97
 
65
- def poll_path
66
- if current_path != '' && params['poll']
67
- root_path + current_path
68
- else
69
- ""
70
- end
71
- end
72
-
73
98
  def text_direction
74
- get_locale['TextDirection'] || 'ltr'
99
+ get_locale["TextDirection"] || "ltr"
75
100
  end
76
101
 
77
102
  def rtl?
78
- text_direction == 'rtl'
103
+ text_direction == "rtl"
79
104
  end
80
105
 
81
106
  # See https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
82
107
  def user_preferred_languages
83
- languages = env['HTTP_ACCEPT_LANGUAGE']
84
- languages.to_s.downcase.gsub(/\s+/, '').split(',').map do |language|
85
- locale, quality = language.split(';q=', 2)
86
- locale = nil if locale == '*' # Ignore wildcards
108
+ languages = env["HTTP_ACCEPT_LANGUAGE"]
109
+ languages.to_s.downcase.gsub(/\s+/, "").split(",").map { |language|
110
+ locale, quality = language.split(";q=", 2)
111
+ locale = nil if locale == "*" # Ignore wildcards
87
112
  quality = quality ? quality.to_f : 1.0
88
113
  [locale, quality]
89
- end.sort do |(_, left), (_, right)|
114
+ }.sort { |(_, left), (_, right)|
90
115
  right <=> left
91
- end.map(&:first).compact
116
+ }.map(&:first).compact
92
117
  end
93
118
 
94
119
  # Given an Accept-Language header like "fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,ru;q=0.2"
@@ -97,31 +122,31 @@ module Sidekiq
97
122
  # Inspiration taken from https://github.com/iain/http_accept_language/blob/master/lib/http_accept_language/parser.rb
98
123
  def locale
99
124
  @locale ||= begin
100
- matched_locale = user_preferred_languages.map do |preferred|
101
- preferred_language = preferred.split('-', 2).first
125
+ matched_locale = user_preferred_languages.map { |preferred|
126
+ preferred_language = preferred.split("-", 2).first
102
127
 
103
- lang_group = available_locales.select do |available|
104
- preferred_language == available.split('-', 2).first
105
- end
128
+ lang_group = available_locales.select { |available|
129
+ preferred_language == available.split("-", 2).first
130
+ }
106
131
 
107
132
  lang_group.find { |lang| lang == preferred } || lang_group.min_by(&:length)
108
- end.compact.first
133
+ }.compact.first
109
134
 
110
- matched_locale || 'en'
135
+ matched_locale || "en"
111
136
  end
112
137
  end
113
138
 
114
- # mperham/sidekiq#3243
139
+ # sidekiq/sidekiq#3243
115
140
  def unfiltered?
116
- yield unless env['PATH_INFO'].start_with?("/filter/")
141
+ yield unless env["PATH_INFO"].start_with?("/filter/")
117
142
  end
118
143
 
119
144
  def get_locale
120
145
  strings(locale)
121
146
  end
122
147
 
123
- def t(msg, options={})
124
- string = get_locale[msg] || strings('en')[msg] || msg
148
+ def t(msg, options = {})
149
+ string = get_locale[msg] || strings("en")[msg] || msg
125
150
  if options.empty?
126
151
  string
127
152
  else
@@ -129,58 +154,72 @@ module Sidekiq
129
154
  end
130
155
  end
131
156
 
132
- def workers
133
- @workers ||= Sidekiq::Workers.new
157
+ def sort_direction_label
158
+ (params[:direction] == "asc") ? "&uarr;" : "&darr;"
159
+ end
160
+
161
+ def workset
162
+ @work ||= Sidekiq::WorkSet.new
134
163
  end
135
164
 
136
165
  def processes
137
166
  @processes ||= Sidekiq::ProcessSet.new
138
167
  end
139
168
 
140
- def stats
141
- @stats ||= Sidekiq::Stats.new
169
+ # Sorts processes by hostname following the natural sort order
170
+ def sorted_processes
171
+ @sorted_processes ||= begin
172
+ return processes unless processes.all? { |p| p["hostname"] }
173
+
174
+ processes.to_a.sort_by do |process|
175
+ # Kudos to `shurikk` on StackOverflow
176
+ # https://stackoverflow.com/a/15170063/575547
177
+ process["hostname"].split(/(\d+)/).map { |a| /\d+/.match?(a) ? a.to_i : a }
178
+ end
179
+ end
142
180
  end
143
181
 
144
- def retries_with_score(score)
145
- Sidekiq.redis do |conn|
146
- conn.zrangebyscore('retry', score, score)
147
- end.map { |msg| Sidekiq.load_json(msg) }
182
+ def busy_weights(capsule_weights)
183
+ # backwards compat with 7.0.0, remove in 7.1
184
+ cw = [capsule_weights].flatten
185
+ cw.map { |hash|
186
+ hash.map { |name, weight| (weight > 0) ? +name << ": " << weight.to_s : name }.join(", ")
187
+ }.join("; ")
148
188
  end
149
189
 
150
- def redis_connection
151
- Sidekiq.redis do |conn|
152
- c = conn.connection
153
- "redis://#{c[:location]}/#{c[:db]}"
154
- end
190
+ def stats
191
+ @stats ||= Sidekiq::Stats.new
155
192
  end
156
193
 
157
- def namespace
158
- @ns ||= Sidekiq.redis { |conn| conn.respond_to?(:namespace) ? conn.namespace : nil }
194
+ def redis_url
195
+ Sidekiq.redis do |conn|
196
+ conn.config.server_url
197
+ end
159
198
  end
160
199
 
161
200
  def redis_info
162
- Sidekiq.redis_info
201
+ Sidekiq.default_configuration.redis_info
163
202
  end
164
203
 
165
204
  def root_path
166
- "#{env['SCRIPT_NAME']}/"
205
+ "#{env["SCRIPT_NAME"]}/"
167
206
  end
168
207
 
169
208
  def current_path
170
- @current_path ||= request.path_info.gsub(/^\//,'')
209
+ @current_path ||= request.path_info.gsub(/^\//, "")
171
210
  end
172
211
 
173
212
  def current_status
174
- workers.size == 0 ? 'idle' : 'active'
213
+ (workset.size == 0) ? "idle" : "active"
175
214
  end
176
215
 
177
216
  def relative_time(time)
178
217
  stamp = time.getutc.iso8601
179
- %{<time class="ltr" dir="ltr" title="#{stamp}" datetime="#{stamp}">#{time}</time>}
218
+ %(<time class="ltr" dir="ltr" title="#{stamp}" datetime="#{stamp}">#{time}</time>)
180
219
  end
181
220
 
182
221
  def job_params(job, score)
183
- "#{score}-#{job['jid']}"
222
+ "#{score}-#{job["jid"]}"
184
223
  end
185
224
 
186
225
  def parse_params(params)
@@ -188,52 +227,58 @@ module Sidekiq
188
227
  [score.to_f, jid]
189
228
  end
190
229
 
191
- SAFE_QPARAMS = %w(page poll)
230
+ SAFE_QPARAMS = %w[page direction]
192
231
 
193
232
  # Merge options with current params, filter safe params, and stringify to query string
194
233
  def qparams(options)
195
- # stringify
196
- options.keys.each do |key|
197
- options[key.to_s] = options.delete(key)
198
- end
234
+ stringified_options = options.transform_keys(&:to_s)
235
+
236
+ to_query_string(params.merge(stringified_options))
237
+ end
199
238
 
200
- params.merge(options).map do |key, value|
239
+ def to_query_string(params)
240
+ params.map { |key, value|
201
241
  SAFE_QPARAMS.include?(key) ? "#{key}=#{CGI.escape(value.to_s)}" : next
202
- end.compact.join("&")
242
+ }.compact.join("&")
203
243
  end
204
244
 
205
245
  def truncate(text, truncate_after_chars = 2000)
206
- truncate_after_chars && text.size > truncate_after_chars ? "#{text[0..truncate_after_chars]}..." : text
246
+ (truncate_after_chars && text.size > truncate_after_chars) ? "#{text[0..truncate_after_chars]}..." : text
207
247
  end
208
248
 
209
249
  def display_args(args, truncate_after_chars = 2000)
210
- args.map do |arg|
211
- h(truncate(to_display(arg), truncate_after_chars))
212
- end.join(", ")
250
+ return "Invalid job payload, args is nil" if args.nil?
251
+ return "Invalid job payload, args must be an Array, not #{args.class.name}" unless args.is_a?(Array)
252
+
253
+ begin
254
+ args.map { |arg|
255
+ h(truncate(to_display(arg), truncate_after_chars))
256
+ }.join(", ")
257
+ rescue
258
+ "Illegal job arguments: #{h args.inspect}"
259
+ end
213
260
  end
214
261
 
215
262
  def csrf_tag
216
- "<input type='hidden' name='authenticity_token' value='#{session[:csrf]}'/>"
263
+ "<input type='hidden' name='authenticity_token' value='#{env[:csrf_token]}'/>"
217
264
  end
218
265
 
219
266
  def to_display(arg)
267
+ arg.inspect
268
+ rescue
220
269
  begin
221
- arg.inspect
222
- rescue
223
- begin
224
- arg.to_s
225
- rescue => ex
226
- "Cannot display argument: [#{ex.class.name}] #{ex.message}"
227
- end
270
+ arg.to_s
271
+ rescue => ex
272
+ "Cannot display argument: [#{ex.class.name}] #{ex.message}"
228
273
  end
229
274
  end
230
275
 
231
- RETRY_JOB_KEYS = Set.new(%w(
276
+ RETRY_JOB_KEYS = Set.new(%w[
232
277
  queue class args retry_count retried_at failed_at
233
278
  jid error_message error_class backtrace
234
279
  error_backtrace enqueued_at retry wrapped
235
- created_at
236
- ))
280
+ created_at tags display_class
281
+ ])
237
282
 
238
283
  def retry_extra_items(retry_job)
239
284
  @retry_extra_items ||= {}.tap do |extra|
@@ -243,24 +288,28 @@ module Sidekiq
243
288
  end
244
289
  end
245
290
 
246
- def number_with_delimiter(number)
247
- begin
248
- Float(number)
249
- rescue ArgumentError, TypeError
250
- return number
291
+ def format_memory(rss_kb)
292
+ return "0" if rss_kb.nil? || rss_kb == 0
293
+
294
+ if rss_kb < 100_000
295
+ "#{number_with_delimiter(rss_kb)} KB"
296
+ elsif rss_kb < 10_000_000
297
+ "#{number_with_delimiter((rss_kb / 1024.0).to_i)} MB"
298
+ else
299
+ "#{number_with_delimiter((rss_kb / (1024.0 * 1024.0)), precision: 1)} GB"
251
300
  end
301
+ end
252
302
 
253
- options = {delimiter: ',', separator: '.'}
254
- parts = number.to_s.to_str.split('.')
255
- parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
256
- parts.join(options[:separator])
303
+ def number_with_delimiter(number, options = {})
304
+ precision = options[:precision] || 0
305
+ %(<span data-nwp="#{precision}">#{number.round(precision)}</span>)
257
306
  end
258
307
 
259
308
  def h(text)
260
309
  ::Rack::Utils.escape_html(text)
261
310
  rescue ArgumentError => e
262
- raise unless e.message.eql?('invalid byte sequence in UTF-8')
263
- text.encode!('UTF-16', 'UTF-8', invalid: :replace, replace: '').encode!('UTF-8', 'UTF-16')
311
+ raise unless e.message.eql?("invalid byte sequence in UTF-8")
312
+ text.encode!("UTF-16", "UTF-8", invalid: :replace, replace: "").encode!("UTF-8", "UTF-16")
264
313
  retry
265
314
  end
266
315
 
@@ -277,7 +326,7 @@ module Sidekiq
277
326
  end
278
327
 
279
328
  def environment_title_prefix
280
- environment = Sidekiq.options[:environment] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
329
+ environment = Sidekiq.default_configuration[:environment] || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
281
330
 
282
331
  "[#{environment.upcase}] " unless environment == "production"
283
332
  end
@@ -287,30 +336,27 @@ module Sidekiq
287
336
  end
288
337
 
289
338
  def server_utc_time
290
- Time.now.utc.strftime('%H:%M:%S UTC')
339
+ Time.now.utc.strftime("%H:%M:%S UTC")
291
340
  end
292
341
 
293
- def redis_connection_and_namespace
294
- @redis_connection_and_namespace ||= begin
295
- namespace_suffix = namespace == nil ? '' : "##{namespace}"
296
- "#{redis_connection}#{namespace_suffix}"
297
- end
342
+ def pollable?
343
+ !(current_path == "" || current_path.start_with?("metrics"))
298
344
  end
299
345
 
300
346
  def retry_or_delete_or_kill(job, params)
301
- if params['retry']
347
+ if params["retry"]
302
348
  job.retry
303
- elsif params['delete']
349
+ elsif params["delete"]
304
350
  job.delete
305
- elsif params['kill']
351
+ elsif params["kill"]
306
352
  job.kill
307
353
  end
308
354
  end
309
355
 
310
356
  def delete_or_add_queue(job, params)
311
- if params['delete']
357
+ if params["delete"]
312
358
  job.delete
313
- elsif params['add_to_queue']
359
+ elsif params["add_to_queue"]
314
360
  job.add_to_queue
315
361
  end
316
362
  end
@@ -1,18 +1,23 @@
1
1
  # frozen_string_literal: true
2
- require 'rack'
2
+
3
+ require "rack"
3
4
 
4
5
  module Sidekiq
5
6
  module WebRouter
6
- GET = 'GET'
7
- DELETE = 'DELETE'
8
- POST = 'POST'
9
- PUT = 'PUT'
10
- PATCH = 'PATCH'
11
- HEAD = 'HEAD'
12
-
13
- ROUTE_PARAMS = 'rack.route_params'
14
- REQUEST_METHOD = 'REQUEST_METHOD'
15
- PATH_INFO = 'PATH_INFO'
7
+ GET = "GET"
8
+ DELETE = "DELETE"
9
+ POST = "POST"
10
+ PUT = "PUT"
11
+ PATCH = "PATCH"
12
+ HEAD = "HEAD"
13
+
14
+ ROUTE_PARAMS = "rack.route_params"
15
+ REQUEST_METHOD = "REQUEST_METHOD"
16
+ PATH_INFO = "PATH_INFO"
17
+
18
+ def head(path, &block)
19
+ route(HEAD, path, &block)
20
+ end
16
21
 
17
22
  def get(path, &block)
18
23
  route(GET, path, &block)
@@ -35,10 +40,9 @@ module Sidekiq
35
40
  end
36
41
 
37
42
  def route(method, path, &block)
38
- @routes ||= { GET => [], POST => [], PUT => [], PATCH => [], DELETE => [], HEAD => [] }
43
+ @routes ||= {GET => [], POST => [], PUT => [], PATCH => [], DELETE => [], HEAD => []}
39
44
 
40
45
  @routes[method] << WebRoute.new(method, path, block)
41
- @routes[HEAD] << WebRoute.new(method, path, block) if method == GET
42
46
  end
43
47
 
44
48
  def match(env)
@@ -50,7 +54,8 @@ module Sidekiq
50
54
  path_info = "/" if path_info == ""
51
55
 
52
56
  @routes[request_method].each do |route|
53
- if params = route.match(request_method, path_info)
57
+ params = route.match(request_method, path_info)
58
+ if params
54
59
  env[ROUTE_PARAMS] = params
55
60
 
56
61
  return WebAction.new(env, route.block)
@@ -64,7 +69,7 @@ module Sidekiq
64
69
  class WebRoute
65
70
  attr_accessor :request_method, :pattern, :block, :name
66
71
 
67
- NAMED_SEGMENTS_PATTERN = /\/([^\/]*):([^\.:$\/]+)/
72
+ NAMED_SEGMENTS_PATTERN = /\/([^\/]*):([^.:$\/]+)/
68
73
 
69
74
  def initialize(request_method, pattern, block)
70
75
  @request_method = request_method
@@ -77,7 +82,7 @@ module Sidekiq
77
82
  end
78
83
 
79
84
  def compile
80
- if pattern.match(NAMED_SEGMENTS_PATTERN)
85
+ if pattern.match?(NAMED_SEGMENTS_PATTERN)
81
86
  p = pattern.gsub(NAMED_SEGMENTS_PATTERN, '/\1(?<\2>[^$/]+)')
82
87
 
83
88
  Regexp.new("\\A#{p}\\Z")
@@ -91,9 +96,8 @@ module Sidekiq
91
96
  when String
92
97
  {} if path == matcher
93
98
  else
94
- if path_match = path.match(matcher)
95
- Hash[path_match.names.map(&:to_sym).zip(path_match.captures)]
96
- end
99
+ path_match = path.match(matcher)
100
+ path_match&.named_captures&.transform_keys(&:to_sym)
97
101
  end
98
102
  end
99
103
  end