sidekiq 5.2.4 → 7.2.4

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 (153) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +672 -8
  3. data/LICENSE.txt +9 -0
  4. data/README.md +48 -51
  5. data/bin/multi_queue_bench +271 -0
  6. data/bin/sidekiq +22 -3
  7. data/bin/sidekiqload +213 -115
  8. data/bin/sidekiqmon +11 -0
  9. data/lib/generators/sidekiq/job_generator.rb +57 -0
  10. data/lib/generators/sidekiq/templates/{worker.rb.erb → job.rb.erb} +2 -2
  11. data/lib/generators/sidekiq/templates/{worker_spec.rb.erb → job_spec.rb.erb} +1 -1
  12. data/lib/generators/sidekiq/templates/{worker_test.rb.erb → job_test.rb.erb} +1 -1
  13. data/lib/sidekiq/api.rb +623 -352
  14. data/lib/sidekiq/capsule.rb +127 -0
  15. data/lib/sidekiq/cli.rb +214 -229
  16. data/lib/sidekiq/client.rb +127 -102
  17. data/lib/sidekiq/component.rb +68 -0
  18. data/lib/sidekiq/config.rb +287 -0
  19. data/lib/sidekiq/deploy.rb +62 -0
  20. data/lib/sidekiq/embedded.rb +61 -0
  21. data/lib/sidekiq/fetch.rb +49 -42
  22. data/lib/sidekiq/job.rb +374 -0
  23. data/lib/sidekiq/job_logger.rb +33 -7
  24. data/lib/sidekiq/job_retry.rb +157 -108
  25. data/lib/sidekiq/job_util.rb +107 -0
  26. data/lib/sidekiq/launcher.rb +206 -106
  27. data/lib/sidekiq/logger.rb +131 -0
  28. data/lib/sidekiq/manager.rb +43 -46
  29. data/lib/sidekiq/metrics/query.rb +156 -0
  30. data/lib/sidekiq/metrics/shared.rb +95 -0
  31. data/lib/sidekiq/metrics/tracking.rb +140 -0
  32. data/lib/sidekiq/middleware/chain.rb +113 -56
  33. data/lib/sidekiq/middleware/current_attributes.rb +95 -0
  34. data/lib/sidekiq/middleware/i18n.rb +7 -7
  35. data/lib/sidekiq/middleware/modules.rb +21 -0
  36. data/lib/sidekiq/monitor.rb +146 -0
  37. data/lib/sidekiq/paginator.rb +28 -16
  38. data/lib/sidekiq/processor.rb +126 -117
  39. data/lib/sidekiq/rails.rb +52 -38
  40. data/lib/sidekiq/redis_client_adapter.rb +111 -0
  41. data/lib/sidekiq/redis_connection.rb +41 -112
  42. data/lib/sidekiq/ring_buffer.rb +29 -0
  43. data/lib/sidekiq/scheduled.rb +112 -50
  44. data/lib/sidekiq/sd_notify.rb +149 -0
  45. data/lib/sidekiq/systemd.rb +24 -0
  46. data/lib/sidekiq/testing/inline.rb +6 -5
  47. data/lib/sidekiq/testing.rb +91 -90
  48. data/lib/sidekiq/transaction_aware_client.rb +51 -0
  49. data/lib/sidekiq/version.rb +3 -1
  50. data/lib/sidekiq/web/action.rb +20 -11
  51. data/lib/sidekiq/web/application.rb +202 -80
  52. data/lib/sidekiq/web/csrf_protection.rb +183 -0
  53. data/lib/sidekiq/web/helpers.rb +165 -114
  54. data/lib/sidekiq/web/router.rb +23 -19
  55. data/lib/sidekiq/web.rb +68 -107
  56. data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
  57. data/lib/sidekiq.rb +92 -182
  58. data/sidekiq.gemspec +25 -16
  59. data/web/assets/images/apple-touch-icon.png +0 -0
  60. data/web/assets/javascripts/application.js +152 -61
  61. data/web/assets/javascripts/base-charts.js +106 -0
  62. data/web/assets/javascripts/chart.min.js +13 -0
  63. data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
  64. data/web/assets/javascripts/dashboard-charts.js +182 -0
  65. data/web/assets/javascripts/dashboard.js +35 -293
  66. data/web/assets/javascripts/metrics.js +298 -0
  67. data/web/assets/stylesheets/application-dark.css +147 -0
  68. data/web/assets/stylesheets/application-rtl.css +10 -93
  69. data/web/assets/stylesheets/application.css +124 -522
  70. data/web/assets/stylesheets/bootstrap.css +1 -1
  71. data/web/locales/ar.yml +71 -65
  72. data/web/locales/cs.yml +62 -62
  73. data/web/locales/da.yml +60 -53
  74. data/web/locales/de.yml +65 -53
  75. data/web/locales/el.yml +43 -24
  76. data/web/locales/en.yml +86 -66
  77. data/web/locales/es.yml +70 -54
  78. data/web/locales/fa.yml +65 -65
  79. data/web/locales/fr.yml +83 -62
  80. data/web/locales/gd.yml +99 -0
  81. data/web/locales/he.yml +65 -64
  82. data/web/locales/hi.yml +59 -59
  83. data/web/locales/it.yml +53 -53
  84. data/web/locales/ja.yml +75 -64
  85. data/web/locales/ko.yml +52 -52
  86. data/web/locales/lt.yml +83 -0
  87. data/web/locales/nb.yml +61 -61
  88. data/web/locales/nl.yml +52 -52
  89. data/web/locales/pl.yml +45 -45
  90. data/web/locales/pt-br.yml +83 -55
  91. data/web/locales/pt.yml +51 -51
  92. data/web/locales/ru.yml +68 -63
  93. data/web/locales/sv.yml +53 -53
  94. data/web/locales/ta.yml +60 -60
  95. data/web/locales/uk.yml +62 -61
  96. data/web/locales/ur.yml +64 -64
  97. data/web/locales/vi.yml +83 -0
  98. data/web/locales/zh-cn.yml +43 -16
  99. data/web/locales/zh-tw.yml +42 -8
  100. data/web/views/_footer.erb +18 -3
  101. data/web/views/_job_info.erb +21 -4
  102. data/web/views/_metrics_period_select.erb +12 -0
  103. data/web/views/_nav.erb +1 -1
  104. data/web/views/_paging.erb +2 -0
  105. data/web/views/_poll_link.erb +3 -6
  106. data/web/views/_summary.erb +7 -7
  107. data/web/views/busy.erb +79 -29
  108. data/web/views/dashboard.erb +48 -18
  109. data/web/views/dead.erb +3 -3
  110. data/web/views/filtering.erb +7 -0
  111. data/web/views/layout.erb +3 -1
  112. data/web/views/metrics.erb +91 -0
  113. data/web/views/metrics_for_job.erb +59 -0
  114. data/web/views/morgue.erb +14 -15
  115. data/web/views/queue.erb +33 -24
  116. data/web/views/queues.erb +19 -5
  117. data/web/views/retries.erb +16 -17
  118. data/web/views/retry.erb +3 -3
  119. data/web/views/scheduled.erb +17 -15
  120. metadata +71 -72
  121. data/.github/contributing.md +0 -32
  122. data/.github/issue_template.md +0 -11
  123. data/.gitignore +0 -15
  124. data/.travis.yml +0 -17
  125. data/3.0-Upgrade.md +0 -70
  126. data/4.0-Upgrade.md +0 -53
  127. data/5.0-Upgrade.md +0 -56
  128. data/Appraisals +0 -9
  129. data/COMM-LICENSE +0 -95
  130. data/Ent-Changes.md +0 -225
  131. data/Gemfile +0 -29
  132. data/LICENSE +0 -9
  133. data/Pro-2.0-Upgrade.md +0 -138
  134. data/Pro-3.0-Upgrade.md +0 -44
  135. data/Pro-4.0-Upgrade.md +0 -35
  136. data/Pro-Changes.md +0 -752
  137. data/Rakefile +0 -9
  138. data/bin/sidekiqctl +0 -237
  139. data/code_of_conduct.md +0 -50
  140. data/gemfiles/rails_4.gemfile +0 -31
  141. data/gemfiles/rails_5.gemfile +0 -31
  142. data/lib/generators/sidekiq/worker_generator.rb +0 -49
  143. data/lib/sidekiq/core_ext.rb +0 -1
  144. data/lib/sidekiq/delay.rb +0 -42
  145. data/lib/sidekiq/exception_handler.rb +0 -29
  146. data/lib/sidekiq/extensions/action_mailer.rb +0 -57
  147. data/lib/sidekiq/extensions/active_record.rb +0 -40
  148. data/lib/sidekiq/extensions/class_methods.rb +0 -40
  149. data/lib/sidekiq/extensions/generic_proxy.rb +0 -31
  150. data/lib/sidekiq/logging.rb +0 -122
  151. data/lib/sidekiq/middleware/server/active_record.rb +0 -23
  152. data/lib/sidekiq/util.rb +0 -66
  153. data/lib/sidekiq/worker.rb +0 -215
@@ -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"
@@ -96,32 +121,36 @@ module Sidekiq
96
121
  #
97
122
  # Inspiration taken from https://github.com/iain/http_accept_language/blob/master/lib/http_accept_language/parser.rb
98
123
  def locale
124
+ # session[:locale] is set via the locale selector from the footer
125
+ # defined?(session) && session are used to avoid exceptions when running tests
126
+ return session[:locale] if defined?(session) && session&.[](:locale)
127
+
99
128
  @locale ||= begin
100
- matched_locale = user_preferred_languages.map do |preferred|
101
- preferred_language = preferred.split('-', 2).first
129
+ matched_locale = user_preferred_languages.map { |preferred|
130
+ preferred_language = preferred.split("-", 2).first
102
131
 
103
- lang_group = available_locales.select do |available|
104
- preferred_language == available.split('-', 2).first
105
- end
132
+ lang_group = available_locales.select { |available|
133
+ preferred_language == available.split("-", 2).first
134
+ }
106
135
 
107
136
  lang_group.find { |lang| lang == preferred } || lang_group.min_by(&:length)
108
- end.compact.first
137
+ }.compact.first
109
138
 
110
- matched_locale || 'en'
139
+ matched_locale || "en"
111
140
  end
112
141
  end
113
142
 
114
- # mperham/sidekiq#3243
143
+ # sidekiq/sidekiq#3243
115
144
  def unfiltered?
116
- yield unless env['PATH_INFO'].start_with?("/filter/")
145
+ yield unless env["PATH_INFO"].start_with?("/filter/")
117
146
  end
118
147
 
119
148
  def get_locale
120
149
  strings(locale)
121
150
  end
122
151
 
123
- def t(msg, options={})
124
- string = get_locale[msg] || strings('en')[msg] || msg
152
+ def t(msg, options = {})
153
+ string = get_locale[msg] || strings("en")[msg] || msg
125
154
  if options.empty?
126
155
  string
127
156
  else
@@ -129,58 +158,72 @@ module Sidekiq
129
158
  end
130
159
  end
131
160
 
132
- def workers
133
- @workers ||= Sidekiq::Workers.new
161
+ def sort_direction_label
162
+ (params[:direction] == "asc") ? "&uarr;" : "&darr;"
163
+ end
164
+
165
+ def workset
166
+ @work ||= Sidekiq::WorkSet.new
134
167
  end
135
168
 
136
169
  def processes
137
170
  @processes ||= Sidekiq::ProcessSet.new
138
171
  end
139
172
 
140
- def stats
141
- @stats ||= Sidekiq::Stats.new
173
+ # Sorts processes by hostname following the natural sort order
174
+ def sorted_processes
175
+ @sorted_processes ||= begin
176
+ return processes unless processes.all? { |p| p["hostname"] }
177
+
178
+ processes.to_a.sort_by do |process|
179
+ # Kudos to `shurikk` on StackOverflow
180
+ # https://stackoverflow.com/a/15170063/575547
181
+ process["hostname"].split(/(\d+)/).map { |a| /\d+/.match?(a) ? a.to_i : a }
182
+ end
183
+ end
142
184
  end
143
185
 
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) }
186
+ def busy_weights(capsule_weights)
187
+ # backwards compat with 7.0.0, remove in 7.1
188
+ cw = [capsule_weights].flatten
189
+ cw.map { |hash|
190
+ hash.map { |name, weight| (weight > 0) ? +name << ": " << weight.to_s : name }.join(", ")
191
+ }.join("; ")
148
192
  end
149
193
 
150
- def redis_connection
151
- Sidekiq.redis do |conn|
152
- c = conn.connection
153
- "redis://#{c[:location]}/#{c[:db]}"
154
- end
194
+ def stats
195
+ @stats ||= Sidekiq::Stats.new
155
196
  end
156
197
 
157
- def namespace
158
- @ns ||= Sidekiq.redis { |conn| conn.respond_to?(:namespace) ? conn.namespace : nil }
198
+ def redis_url
199
+ Sidekiq.redis do |conn|
200
+ conn.config.server_url
201
+ end
159
202
  end
160
203
 
161
204
  def redis_info
162
- Sidekiq.redis_info
205
+ Sidekiq.default_configuration.redis_info
163
206
  end
164
207
 
165
208
  def root_path
166
- "#{env['SCRIPT_NAME']}/"
209
+ "#{env["SCRIPT_NAME"]}/"
167
210
  end
168
211
 
169
212
  def current_path
170
- @current_path ||= request.path_info.gsub(/^\//,'')
213
+ @current_path ||= request.path_info.gsub(/^\//, "")
171
214
  end
172
215
 
173
216
  def current_status
174
- workers.size == 0 ? 'idle' : 'active'
217
+ (workset.size == 0) ? "idle" : "active"
175
218
  end
176
219
 
177
220
  def relative_time(time)
178
221
  stamp = time.getutc.iso8601
179
- %{<time class="ltr" dir="ltr" title="#{stamp}" datetime="#{stamp}">#{time}</time>}
222
+ %(<time class="ltr" dir="ltr" title="#{stamp}" datetime="#{stamp}">#{time}</time>)
180
223
  end
181
224
 
182
225
  def job_params(job, score)
183
- "#{score}-#{job['jid']}"
226
+ "#{score}-#{job["jid"]}"
184
227
  end
185
228
 
186
229
  def parse_params(params)
@@ -188,52 +231,58 @@ module Sidekiq
188
231
  [score.to_f, jid]
189
232
  end
190
233
 
191
- SAFE_QPARAMS = %w(page poll)
234
+ SAFE_QPARAMS = %w[page direction]
192
235
 
193
236
  # Merge options with current params, filter safe params, and stringify to query string
194
237
  def qparams(options)
195
- # stringify
196
- options.keys.each do |key|
197
- options[key.to_s] = options.delete(key)
198
- end
238
+ stringified_options = options.transform_keys(&:to_s)
239
+
240
+ to_query_string(params.merge(stringified_options))
241
+ end
199
242
 
200
- params.merge(options).map do |key, value|
243
+ def to_query_string(params)
244
+ params.map { |key, value|
201
245
  SAFE_QPARAMS.include?(key) ? "#{key}=#{CGI.escape(value.to_s)}" : next
202
- end.compact.join("&")
246
+ }.compact.join("&")
203
247
  end
204
248
 
205
249
  def truncate(text, truncate_after_chars = 2000)
206
- truncate_after_chars && text.size > truncate_after_chars ? "#{text[0..truncate_after_chars]}..." : text
250
+ (truncate_after_chars && text.size > truncate_after_chars) ? "#{text[0..truncate_after_chars]}..." : text
207
251
  end
208
252
 
209
253
  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(", ")
254
+ return "Invalid job payload, args is nil" if args.nil?
255
+ return "Invalid job payload, args must be an Array, not #{args.class.name}" unless args.is_a?(Array)
256
+
257
+ begin
258
+ args.map { |arg|
259
+ h(truncate(to_display(arg), truncate_after_chars))
260
+ }.join(", ")
261
+ rescue
262
+ "Illegal job arguments: #{h args.inspect}"
263
+ end
213
264
  end
214
265
 
215
266
  def csrf_tag
216
- "<input type='hidden' name='authenticity_token' value='#{session[:csrf]}'/>"
267
+ "<input type='hidden' name='authenticity_token' value='#{env[:csrf_token]}'/>"
217
268
  end
218
269
 
219
270
  def to_display(arg)
271
+ arg.inspect
272
+ rescue
220
273
  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
274
+ arg.to_s
275
+ rescue => ex
276
+ "Cannot display argument: [#{ex.class.name}] #{ex.message}"
228
277
  end
229
278
  end
230
279
 
231
- RETRY_JOB_KEYS = Set.new(%w(
280
+ RETRY_JOB_KEYS = Set.new(%w[
232
281
  queue class args retry_count retried_at failed_at
233
282
  jid error_message error_class backtrace
234
283
  error_backtrace enqueued_at retry wrapped
235
- created_at
236
- ))
284
+ created_at tags display_class
285
+ ])
237
286
 
238
287
  def retry_extra_items(retry_job)
239
288
  @retry_extra_items ||= {}.tap do |extra|
@@ -243,24 +292,28 @@ module Sidekiq
243
292
  end
244
293
  end
245
294
 
246
- def number_with_delimiter(number)
247
- begin
248
- Float(number)
249
- rescue ArgumentError, TypeError
250
- return number
295
+ def format_memory(rss_kb)
296
+ return "0" if rss_kb.nil? || rss_kb == 0
297
+
298
+ if rss_kb < 100_000
299
+ "#{number_with_delimiter(rss_kb)} KB"
300
+ elsif rss_kb < 10_000_000
301
+ "#{number_with_delimiter((rss_kb / 1024.0).to_i)} MB"
302
+ else
303
+ "#{number_with_delimiter((rss_kb / (1024.0 * 1024.0)), precision: 1)} GB"
251
304
  end
305
+ end
252
306
 
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])
307
+ def number_with_delimiter(number, options = {})
308
+ precision = options[:precision] || 0
309
+ %(<span data-nwp="#{precision}">#{number.round(precision)}</span>)
257
310
  end
258
311
 
259
312
  def h(text)
260
313
  ::Rack::Utils.escape_html(text)
261
314
  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')
315
+ raise unless e.message.eql?("invalid byte sequence in UTF-8")
316
+ text.encode!("UTF-16", "UTF-8", invalid: :replace, replace: "").encode!("UTF-8", "UTF-16")
264
317
  retry
265
318
  end
266
319
 
@@ -277,7 +330,7 @@ module Sidekiq
277
330
  end
278
331
 
279
332
  def environment_title_prefix
280
- environment = Sidekiq.options[:environment] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
333
+ environment = Sidekiq.default_configuration[:environment] || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
281
334
 
282
335
  "[#{environment.upcase}] " unless environment == "production"
283
336
  end
@@ -287,30 +340,28 @@ module Sidekiq
287
340
  end
288
341
 
289
342
  def server_utc_time
290
- Time.now.utc.strftime('%H:%M:%S UTC')
343
+ Time.now.utc.strftime("%H:%M:%S UTC")
291
344
  end
292
345
 
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
346
+ def pollable?
347
+ # there's no point to refreshing the metrics pages every N seconds
348
+ !(current_path == "" || current_path.index("metrics"))
298
349
  end
299
350
 
300
351
  def retry_or_delete_or_kill(job, params)
301
- if params['retry']
352
+ if params["retry"]
302
353
  job.retry
303
- elsif params['delete']
354
+ elsif params["delete"]
304
355
  job.delete
305
- elsif params['kill']
356
+ elsif params["kill"]
306
357
  job.kill
307
358
  end
308
359
  end
309
360
 
310
361
  def delete_or_add_queue(job, params)
311
- if params['delete']
362
+ if params["delete"]
312
363
  job.delete
313
- elsif params['add_to_queue']
364
+ elsif params["add_to_queue"]
314
365
  job.add_to_queue
315
366
  end
316
367
  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