sidekiq 6.4.1 → 7.2.1

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 (116) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +307 -12
  3. data/README.md +43 -35
  4. data/bin/multi_queue_bench +268 -0
  5. data/bin/sidekiq +3 -8
  6. data/bin/sidekiqload +206 -114
  7. data/bin/sidekiqmon +3 -0
  8. data/lib/sidekiq/api.rb +356 -167
  9. data/lib/sidekiq/capsule.rb +127 -0
  10. data/lib/sidekiq/cli.rb +85 -89
  11. data/lib/sidekiq/client.rb +87 -59
  12. data/lib/sidekiq/component.rb +68 -0
  13. data/lib/sidekiq/config.rb +287 -0
  14. data/lib/sidekiq/deploy.rb +62 -0
  15. data/lib/sidekiq/embedded.rb +61 -0
  16. data/lib/sidekiq/fetch.rb +21 -22
  17. data/lib/sidekiq/job.rb +371 -10
  18. data/lib/sidekiq/job_logger.rb +2 -2
  19. data/lib/sidekiq/job_retry.rb +97 -58
  20. data/lib/sidekiq/job_util.rb +62 -20
  21. data/lib/sidekiq/launcher.rb +91 -83
  22. data/lib/sidekiq/logger.rb +6 -45
  23. data/lib/sidekiq/manager.rb +33 -32
  24. data/lib/sidekiq/metrics/query.rb +156 -0
  25. data/lib/sidekiq/metrics/shared.rb +95 -0
  26. data/lib/sidekiq/metrics/tracking.rb +140 -0
  27. data/lib/sidekiq/middleware/chain.rb +96 -51
  28. data/lib/sidekiq/middleware/current_attributes.rb +58 -20
  29. data/lib/sidekiq/middleware/i18n.rb +6 -4
  30. data/lib/sidekiq/middleware/modules.rb +21 -0
  31. data/lib/sidekiq/monitor.rb +17 -4
  32. data/lib/sidekiq/paginator.rb +11 -3
  33. data/lib/sidekiq/processor.rb +81 -80
  34. data/lib/sidekiq/rails.rb +21 -14
  35. data/lib/sidekiq/redis_client_adapter.rb +111 -0
  36. data/lib/sidekiq/redis_connection.rb +16 -85
  37. data/lib/sidekiq/ring_buffer.rb +29 -0
  38. data/lib/sidekiq/scheduled.rb +66 -38
  39. data/lib/sidekiq/testing/inline.rb +4 -4
  40. data/lib/sidekiq/testing.rb +67 -75
  41. data/lib/sidekiq/transaction_aware_client.rb +44 -0
  42. data/lib/sidekiq/version.rb +2 -1
  43. data/lib/sidekiq/web/action.rb +3 -3
  44. data/lib/sidekiq/web/application.rb +107 -10
  45. data/lib/sidekiq/web/csrf_protection.rb +8 -5
  46. data/lib/sidekiq/web/helpers.rb +65 -43
  47. data/lib/sidekiq/web.rb +19 -14
  48. data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
  49. data/lib/sidekiq.rb +84 -207
  50. data/sidekiq.gemspec +12 -10
  51. data/web/assets/javascripts/application.js +92 -26
  52. data/web/assets/javascripts/base-charts.js +106 -0
  53. data/web/assets/javascripts/chart.min.js +13 -0
  54. data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
  55. data/web/assets/javascripts/dashboard-charts.js +182 -0
  56. data/web/assets/javascripts/dashboard.js +10 -249
  57. data/web/assets/javascripts/metrics.js +298 -0
  58. data/web/assets/stylesheets/application-dark.css +4 -0
  59. data/web/assets/stylesheets/application-rtl.css +2 -91
  60. data/web/assets/stylesheets/application.css +75 -299
  61. data/web/locales/ar.yml +70 -70
  62. data/web/locales/cs.yml +62 -62
  63. data/web/locales/da.yml +60 -53
  64. data/web/locales/de.yml +65 -65
  65. data/web/locales/el.yml +43 -24
  66. data/web/locales/en.yml +84 -69
  67. data/web/locales/es.yml +68 -68
  68. data/web/locales/fa.yml +65 -65
  69. data/web/locales/fr.yml +81 -67
  70. data/web/locales/gd.yml +99 -0
  71. data/web/locales/he.yml +65 -64
  72. data/web/locales/hi.yml +59 -59
  73. data/web/locales/it.yml +53 -53
  74. data/web/locales/ja.yml +73 -68
  75. data/web/locales/ko.yml +52 -52
  76. data/web/locales/lt.yml +66 -66
  77. data/web/locales/nb.yml +61 -61
  78. data/web/locales/nl.yml +52 -52
  79. data/web/locales/pl.yml +45 -45
  80. data/web/locales/pt-br.yml +83 -55
  81. data/web/locales/pt.yml +51 -51
  82. data/web/locales/ru.yml +67 -66
  83. data/web/locales/sv.yml +53 -53
  84. data/web/locales/ta.yml +60 -60
  85. data/web/locales/uk.yml +62 -61
  86. data/web/locales/ur.yml +64 -64
  87. data/web/locales/vi.yml +67 -67
  88. data/web/locales/zh-cn.yml +43 -16
  89. data/web/locales/zh-tw.yml +42 -8
  90. data/web/views/_footer.erb +5 -2
  91. data/web/views/_job_info.erb +18 -2
  92. data/web/views/_metrics_period_select.erb +12 -0
  93. data/web/views/_nav.erb +1 -1
  94. data/web/views/_paging.erb +2 -0
  95. data/web/views/_poll_link.erb +1 -1
  96. data/web/views/_summary.erb +7 -7
  97. data/web/views/busy.erb +50 -34
  98. data/web/views/dashboard.erb +26 -4
  99. data/web/views/filtering.erb +7 -0
  100. data/web/views/metrics.erb +91 -0
  101. data/web/views/metrics_for_job.erb +59 -0
  102. data/web/views/morgue.erb +5 -9
  103. data/web/views/queue.erb +15 -15
  104. data/web/views/queues.erb +9 -3
  105. data/web/views/retries.erb +5 -9
  106. data/web/views/scheduled.erb +12 -13
  107. metadata +58 -27
  108. data/lib/sidekiq/delay.rb +0 -43
  109. data/lib/sidekiq/exception_handler.rb +0 -27
  110. data/lib/sidekiq/extensions/action_mailer.rb +0 -48
  111. data/lib/sidekiq/extensions/active_record.rb +0 -43
  112. data/lib/sidekiq/extensions/class_methods.rb +0 -43
  113. data/lib/sidekiq/extensions/generic_proxy.rb +0 -33
  114. data/lib/sidekiq/util.rb +0 -108
  115. data/lib/sidekiq/worker.rb +0 -362
  116. /data/{LICENSE → LICENSE.txt} +0 -0
@@ -0,0 +1,127 @@
1
+ require "sidekiq/component"
2
+
3
+ module Sidekiq
4
+ # A Sidekiq::Capsule is the set of resources necessary to
5
+ # process one or more queues with a given concurrency.
6
+ # One "default" Capsule is started but the user may declare additional
7
+ # Capsules in their initializer.
8
+ #
9
+ # This capsule will pull jobs from the "single" queue and process
10
+ # the jobs with one thread, meaning the jobs will be processed serially.
11
+ #
12
+ # Sidekiq.configure_server do |config|
13
+ # config.capsule("single-threaded") do |cap|
14
+ # cap.concurrency = 1
15
+ # cap.queues = %w(single)
16
+ # end
17
+ # end
18
+ class Capsule
19
+ include Sidekiq::Component
20
+
21
+ attr_reader :name
22
+ attr_reader :queues
23
+ attr_accessor :concurrency
24
+ attr_reader :mode
25
+ attr_reader :weights
26
+
27
+ def initialize(name, config)
28
+ @name = name
29
+ @config = config
30
+ @queues = ["default"]
31
+ @weights = {"default" => 0}
32
+ @concurrency = config[:concurrency]
33
+ @mode = :strict
34
+ end
35
+
36
+ def fetcher
37
+ @fetcher ||= begin
38
+ inst = (config[:fetch_class] || Sidekiq::BasicFetch).new(self)
39
+ inst.setup(config[:fetch_setup]) if inst.respond_to?(:setup)
40
+ inst
41
+ end
42
+ end
43
+
44
+ def stop
45
+ fetcher&.bulk_requeue([])
46
+ end
47
+
48
+ # Sidekiq checks queues in three modes:
49
+ # - :strict - all queues have 0 weight and are checked strictly in order
50
+ # - :weighted - queues have arbitrary weight between 1 and N
51
+ # - :random - all queues have weight of 1
52
+ def queues=(val)
53
+ @weights = {}
54
+ @queues = Array(val).each_with_object([]) do |qstr, memo|
55
+ arr = qstr
56
+ arr = qstr.split(",") if qstr.is_a?(String)
57
+ name, weight = arr
58
+ @weights[name] = weight.to_i
59
+ [weight.to_i, 1].max.times do
60
+ memo << name
61
+ end
62
+ end
63
+ @mode = if @weights.values.all?(&:zero?)
64
+ :strict
65
+ elsif @weights.values.all? { |x| x == 1 }
66
+ :random
67
+ else
68
+ :weighted
69
+ end
70
+ end
71
+
72
+ # Allow the middleware to be different per-capsule.
73
+ # Avoid if possible and add middleware globally so all
74
+ # capsules share the same chains. Easier to debug that way.
75
+ def client_middleware
76
+ @client_chain ||= config.client_middleware.copy_for(self)
77
+ yield @client_chain if block_given?
78
+ @client_chain
79
+ end
80
+
81
+ def server_middleware
82
+ @server_chain ||= config.server_middleware.copy_for(self)
83
+ yield @server_chain if block_given?
84
+ @server_chain
85
+ end
86
+
87
+ def redis_pool
88
+ Thread.current[:sidekiq_redis_pool] || local_redis_pool
89
+ end
90
+
91
+ def local_redis_pool
92
+ # connection pool is lazy, it will not create connections unless you actually need them
93
+ # so don't be skimpy!
94
+ @redis ||= config.new_redis_pool(@concurrency, name)
95
+ end
96
+
97
+ def redis
98
+ raise ArgumentError, "requires a block" unless block_given?
99
+ redis_pool.with do |conn|
100
+ retryable = true
101
+ begin
102
+ yield conn
103
+ rescue RedisClientAdapter::BaseError => ex
104
+ # 2550 Failover can cause the server to become a replica, need
105
+ # to disconnect and reopen the socket to get back to the primary.
106
+ # 4495 Use the same logic if we have a "Not enough replicas" error from the primary
107
+ # 4985 Use the same logic when a blocking command is force-unblocked
108
+ # The same retry logic is also used in client.rb
109
+ if retryable && ex.message =~ /READONLY|NOREPLICAS|UNBLOCKED/
110
+ conn.close
111
+ retryable = false
112
+ retry
113
+ end
114
+ raise
115
+ end
116
+ end
117
+ end
118
+
119
+ def lookup(name)
120
+ config.lookup(name)
121
+ end
122
+
123
+ def logger
124
+ config.logger
125
+ end
126
+ end
127
+ end
data/lib/sidekiq/cli.rb CHANGED
@@ -9,18 +9,23 @@ require "erb"
9
9
  require "fileutils"
10
10
 
11
11
  require "sidekiq"
12
+ require "sidekiq/config"
13
+ require "sidekiq/component"
14
+ require "sidekiq/capsule"
12
15
  require "sidekiq/launcher"
13
- require "sidekiq/util"
14
16
 
15
- module Sidekiq
17
+ module Sidekiq # :nodoc:
16
18
  class CLI
17
- include Util
19
+ include Sidekiq::Component
18
20
  include Singleton unless $TESTING
19
21
 
20
22
  attr_accessor :launcher
21
23
  attr_accessor :environment
24
+ attr_accessor :config
25
+
26
+ def parse(args = ARGV.dup)
27
+ @config ||= Sidekiq.default_configuration
22
28
 
23
- def parse(args = ARGV)
24
29
  setup_options(args)
25
30
  initialize_logger
26
31
  validate!
@@ -36,7 +41,7 @@ module Sidekiq
36
41
  def run(boot_app: true)
37
42
  boot_application if boot_app
38
43
 
39
- if environment == "development" && $stdout.tty? && Sidekiq.log_formatter.is_a?(Sidekiq::Logger::Formatters::Pretty)
44
+ if environment == "development" && $stdout.tty? && @config.logger.formatter.is_a?(Sidekiq::Logger::Formatters::Pretty)
40
45
  print_banner
41
46
  end
42
47
  logger.info "Booted Rails #{::Rails.version} application in #{environment} environment" if rails_app?
@@ -67,40 +72,41 @@ module Sidekiq
67
72
 
68
73
  # touch the connection pool so it is created before we
69
74
  # fire startup and start multithreading.
70
- info = Sidekiq.redis_info
71
- ver = info["redis_version"]
72
- raise "You are connecting to Redis v#{ver}, Sidekiq requires Redis v4.0.0 or greater" if ver < "4"
75
+ info = @config.redis_info
76
+ ver = Gem::Version.new(info["redis_version"])
77
+ raise "You are connecting to Redis #{ver}, Sidekiq requires Redis 6.2.0 or greater" if ver < Gem::Version.new("6.2.0")
73
78
 
74
79
  maxmemory_policy = info["maxmemory_policy"]
75
- if maxmemory_policy != "noeviction"
80
+ if maxmemory_policy != "noeviction" && maxmemory_policy != ""
81
+ # Redis Enterprise Cloud returns "" for their policy 😳
76
82
  logger.warn <<~EOM
77
83
 
78
84
 
79
85
  WARNING: Your Redis instance will evict Sidekiq data under heavy load.
80
86
  The 'noeviction' maxmemory policy is recommended (current policy: '#{maxmemory_policy}').
81
- See: https://github.com/mperham/sidekiq/wiki/Using-Redis#memory
87
+ See: https://github.com/sidekiq/sidekiq/wiki/Using-Redis#memory
82
88
 
83
89
  EOM
84
90
  end
85
91
 
86
92
  # Since the user can pass us a connection pool explicitly in the initializer, we
87
93
  # need to verify the size is large enough or else Sidekiq's performance is dramatically slowed.
88
- cursize = Sidekiq.redis_pool.size
89
- needed = Sidekiq.options[:concurrency] + 2
90
- raise "Your pool of #{cursize} Redis connections is too small, please increase the size to at least #{needed}" if cursize < needed
94
+ @config.capsules.each_pair do |name, cap|
95
+ raise ArgumentError, "Pool size too small for #{name}" if cap.redis_pool.size < cap.concurrency
96
+ end
91
97
 
92
98
  # cache process identity
93
- Sidekiq.options[:identity] = identity
99
+ @config[:identity] = identity
94
100
 
95
101
  # Touch middleware so it isn't lazy loaded by multiple threads, #3043
96
- Sidekiq.server_middleware
102
+ @config.server_middleware
97
103
 
98
104
  # Before this point, the process is initializing with just the main thread.
99
105
  # Starting here the process will now have multiple threads running.
100
106
  fire_event(:startup, reverse: false, reraise: true)
101
107
 
102
- logger.debug { "Client Middleware: #{Sidekiq.client_middleware.map(&:klass).join(", ")}" }
103
- logger.debug { "Server Middleware: #{Sidekiq.server_middleware.map(&:klass).join(", ")}" }
108
+ logger.debug { "Client Middleware: #{@config.default_capsule.client_middleware.map(&:klass).join(", ")}" }
109
+ logger.debug { "Server Middleware: #{@config.default_capsule.server_middleware.map(&:klass).join(", ")}" }
104
110
 
105
111
  launch(self_read)
106
112
  end
@@ -110,13 +116,13 @@ module Sidekiq
110
116
  logger.info "Starting processing, hit Ctrl-C to stop"
111
117
  end
112
118
 
113
- @launcher = Sidekiq::Launcher.new(options)
119
+ @launcher = Sidekiq::Launcher.new(@config)
114
120
 
115
121
  begin
116
122
  launcher.run
117
123
 
118
- while (readable_io = self_read.wait_readable)
119
- signal = readable_io.gets.strip
124
+ while self_read.wait_readable
125
+ signal = self_read.gets.strip
120
126
  handle_signal(signal)
121
127
  end
122
128
  rescue Interrupt
@@ -133,19 +139,34 @@ module Sidekiq
133
139
  end
134
140
  end
135
141
 
136
- def self.w
137
- "\e[37m"
142
+ HOLIDAY_COLORS = {
143
+ # got other color-specific holidays from around the world?
144
+ # https://developer-book.com/post/definitive-guide-for-colored-text-in-terminal/#256-color-escape-codes
145
+ "3-17" => "\e[1;32m", # St. Patrick's Day green
146
+ "10-31" => "\e[38;5;208m" # Halloween orange
147
+ }
148
+
149
+ def self.day
150
+ @@day ||= begin
151
+ t = Date.today
152
+ "#{t.month}-#{t.day}"
153
+ end
138
154
  end
139
155
 
140
156
  def self.r
141
- "\e[31m"
157
+ @@r ||= HOLIDAY_COLORS[day] || "\e[1;31m"
142
158
  end
143
159
 
144
160
  def self.b
145
- "\e[30m"
161
+ @@b ||= HOLIDAY_COLORS[day] || "\e[30m"
162
+ end
163
+
164
+ def self.w
165
+ "\e[1;37m"
146
166
  end
147
167
 
148
168
  def self.reset
169
+ @@b = @@r = @@day = nil
149
170
  "\e[0m"
150
171
  end
151
172
 
@@ -158,7 +179,7 @@ module Sidekiq
158
179
  #{w} ,$$$$$b#{b}/#{w}md$$$P^'
159
180
  #{w} .d$$$$$$#{b}/#{w}$$$P'
160
181
  #{w} $$^' `"#{b}/#{w}$$$' #{r}____ _ _ _ _
161
- #{w} $: ,$$: #{r} / ___|(_) __| | ___| | _(_) __ _
182
+ #{w} $: #{b}'#{w},$$: #{r} / ___|(_) __| | ___| | _(_) __ _
162
183
  #{w} `b :$$ #{r} \\___ \\| |/ _` |/ _ \\ |/ / |/ _` |
163
184
  #{w} $$: #{r} ___) | | (_| | __/ <| | (_| |
164
185
  #{w} $$ #{r}|____/|_|\\__,_|\\___|_|\\_\\_|\\__, |
@@ -173,25 +194,25 @@ module Sidekiq
173
194
  # Heroku sends TERM and then waits 30 seconds for process to exit.
174
195
  "TERM" => ->(cli) { raise Interrupt },
175
196
  "TSTP" => ->(cli) {
176
- Sidekiq.logger.info "Received TSTP, no longer accepting new work"
197
+ cli.logger.info "Received TSTP, no longer accepting new work"
177
198
  cli.launcher.quiet
178
199
  },
179
200
  "TTIN" => ->(cli) {
180
201
  Thread.list.each do |thread|
181
- Sidekiq.logger.warn "Thread TID-#{(thread.object_id ^ ::Process.pid).to_s(36)} #{thread.name}"
202
+ cli.logger.warn "Thread TID-#{(thread.object_id ^ ::Process.pid).to_s(36)} #{thread.name}"
182
203
  if thread.backtrace
183
- Sidekiq.logger.warn thread.backtrace.join("\n")
204
+ cli.logger.warn thread.backtrace.join("\n")
184
205
  else
185
- Sidekiq.logger.warn "<no backtrace available>"
206
+ cli.logger.warn "<no backtrace available>"
186
207
  end
187
208
  end
188
209
  }
189
210
  }
190
- UNHANDLED_SIGNAL_HANDLER = ->(cli) { Sidekiq.logger.info "No signal handler registered, ignoring" }
211
+ UNHANDLED_SIGNAL_HANDLER = ->(cli) { cli.logger.info "No signal handler registered, ignoring" }
191
212
  SIGNAL_HANDLERS.default = UNHANDLED_SIGNAL_HANDLER
192
213
 
193
214
  def handle_signal(sig)
194
- Sidekiq.logger.debug "Got #{sig} signal"
215
+ logger.debug "Got #{sig} signal"
195
216
  SIGNAL_HANDLERS[sig].call(self)
196
217
  end
197
218
 
@@ -209,6 +230,7 @@ module Sidekiq
209
230
  # Both Sinatra 2.0+ and Sidekiq support this term.
210
231
  # RAILS_ENV and RACK_ENV are there for legacy support.
211
232
  @environment = cli_env || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
233
+ config[:environment] = @environment
212
234
  end
213
235
 
214
236
  def symbolize_keys_deep!(hash)
@@ -237,7 +259,7 @@ module Sidekiq
237
259
  config_dir = if File.directory?(opts[:require].to_s)
238
260
  File.join(opts[:require], "config")
239
261
  else
240
- File.join(options[:require], "config")
262
+ File.join(@config[:require], "config")
241
263
  end
242
264
 
243
265
  %w[sidekiq.yml sidekiq.yml.erb].each do |config_file|
@@ -254,27 +276,34 @@ module Sidekiq
254
276
  opts[:concurrency] = Integer(ENV["RAILS_MAX_THREADS"]) if opts[:concurrency].nil? && ENV["RAILS_MAX_THREADS"]
255
277
 
256
278
  # merge with defaults
257
- options.merge!(opts)
258
- end
279
+ @config.merge!(opts)
280
+
281
+ @config.default_capsule.tap do |cap|
282
+ cap.queues = opts[:queues]
283
+ cap.concurrency = opts[:concurrency] || @config[:concurrency]
284
+ end
259
285
 
260
- def options
261
- Sidekiq.options
286
+ opts[:capsules]&.each do |name, cap_config|
287
+ @config.capsule(name.to_s) do |cap|
288
+ cap.queues = cap_config[:queues]
289
+ cap.concurrency = cap_config[:concurrency]
290
+ end
291
+ end
262
292
  end
263
293
 
264
294
  def boot_application
265
295
  ENV["RACK_ENV"] = ENV["RAILS_ENV"] = environment
266
296
 
267
- if File.directory?(options[:require])
297
+ if File.directory?(@config[:require])
268
298
  require "rails"
269
- if ::Rails::VERSION::MAJOR < 5
270
- raise "Sidekiq no longer supports this version of Rails"
271
- else
272
- require "sidekiq/rails"
273
- require File.expand_path("#{options[:require]}/config/environment.rb")
299
+ if ::Rails::VERSION::MAJOR < 6
300
+ warn "Sidekiq #{Sidekiq::VERSION} only supports Rails 6+"
274
301
  end
275
- options[:tag] ||= default_tag
302
+ require "sidekiq/rails"
303
+ require File.expand_path("#{@config[:require]}/config/environment.rb")
304
+ @config[:tag] ||= default_tag
276
305
  else
277
- require options[:require]
306
+ require @config[:require]
278
307
  end
279
308
  end
280
309
 
@@ -291,18 +320,18 @@ module Sidekiq
291
320
  end
292
321
 
293
322
  def validate!
294
- if !File.exist?(options[:require]) ||
295
- (File.directory?(options[:require]) && !File.exist?("#{options[:require]}/config/application.rb"))
323
+ if !File.exist?(@config[:require]) ||
324
+ (File.directory?(@config[:require]) && !File.exist?("#{@config[:require]}/config/application.rb"))
296
325
  logger.info "=================================================================="
297
326
  logger.info " Please point Sidekiq to a Rails application or a Ruby file "
298
- logger.info " to load your worker classes with -r [DIR|FILE]."
327
+ logger.info " to load your job classes with -r [DIR|FILE]."
299
328
  logger.info "=================================================================="
300
329
  logger.info @parser
301
330
  die(1)
302
331
  end
303
332
 
304
333
  [:concurrency, :timeout].each do |opt|
305
- raise ArgumentError, "#{opt}: #{options[opt]} is not a valid value" if options.key?(opt) && options[opt].to_i <= 0
334
+ raise ArgumentError, "#{opt}: #{@config[opt]} is not a valid value" if @config[opt].to_i <= 0
306
335
  end
307
336
  end
308
337
 
@@ -319,10 +348,6 @@ module Sidekiq
319
348
  opts[:concurrency] = Integer(arg)
320
349
  end
321
350
 
322
- o.on "-d", "--daemon", "Daemonize process" do |arg|
323
- puts "ERROR: Daemonization mode was removed in Sidekiq 6.0, please use a proper process supervisor to start and manage your services"
324
- end
325
-
326
351
  o.on "-e", "--environment ENV", "Application environment" do |arg|
327
352
  opts[:environment] = arg
328
353
  end
@@ -332,11 +357,11 @@ module Sidekiq
332
357
  end
333
358
 
334
359
  o.on "-q", "--queue QUEUE[,WEIGHT]", "Queues to process with optional weights" do |arg|
335
- queue, weight = arg.split(",")
336
- parse_queue opts, queue, weight
360
+ opts[:queues] ||= []
361
+ opts[:queues] << arg
337
362
  end
338
363
 
339
- o.on "-r", "--require [PATH|DIR]", "Location of Rails application with workers or file to require" do |arg|
364
+ o.on "-r", "--require [PATH|DIR]", "Location of Rails application with jobs or file to require" do |arg|
340
365
  opts[:require] = arg
341
366
  end
342
367
 
@@ -352,15 +377,7 @@ module Sidekiq
352
377
  opts[:config_file] = arg
353
378
  end
354
379
 
355
- o.on "-L", "--logfile PATH", "path to writable logfile" do |arg|
356
- puts "ERROR: Logfile redirection was removed in Sidekiq 6.0, Sidekiq will only log to STDOUT"
357
- end
358
-
359
- o.on "-P", "--pidfile PATH", "path to pidfile" do |arg|
360
- puts "ERROR: PID file creation was removed in Sidekiq 6.0, please use a proper process supervisor to start and manage your services"
361
- end
362
-
363
- o.on "-V", "--version", "Print version and exit" do |arg|
380
+ o.on "-V", "--version", "Print version and exit" do
364
381
  puts "Sidekiq #{Sidekiq::VERSION}"
365
382
  die(0)
366
383
  end
@@ -376,13 +393,13 @@ module Sidekiq
376
393
  end
377
394
 
378
395
  def initialize_logger
379
- Sidekiq.logger.level = ::Logger::DEBUG if options[:verbose]
396
+ @config.logger.level = ::Logger::DEBUG if @config[:verbose]
380
397
  end
381
398
 
382
399
  def parse_config(path)
383
- erb = ERB.new(File.read(path))
400
+ erb = ERB.new(File.read(path), trim_mode: "-")
384
401
  erb.filename = File.expand_path(path)
385
- opts = load_yaml(erb.result) || {}
402
+ opts = YAML.safe_load(erb.result, permitted_classes: [Symbol], aliases: true) || {}
386
403
 
387
404
  if opts.respond_to? :deep_symbolize_keys!
388
405
  opts.deep_symbolize_keys!
@@ -393,31 +410,9 @@ module Sidekiq
393
410
  opts = opts.merge(opts.delete(environment.to_sym) || {})
394
411
  opts.delete(:strict)
395
412
 
396
- parse_queues(opts, opts.delete(:queues) || [])
397
-
398
413
  opts
399
414
  end
400
415
 
401
- def load_yaml(src)
402
- if Psych::VERSION > "4.0"
403
- YAML.safe_load(src, permitted_classes: [Symbol], aliases: true)
404
- else
405
- YAML.load(src)
406
- end
407
- end
408
-
409
- def parse_queues(opts, queues_and_weights)
410
- queues_and_weights.each { |queue_and_weight| parse_queue(opts, *queue_and_weight) }
411
- end
412
-
413
- def parse_queue(opts, queue, weight = nil)
414
- opts[:queues] ||= []
415
- opts[:strict] = true if opts[:strict].nil?
416
- raise ArgumentError, "queues: #{queue} cannot be defined twice" if opts[:queues].include?(queue)
417
- [weight.to_i, 1].max.times { opts[:queues] << queue.to_s }
418
- opts[:strict] = false if weight.to_i > 0
419
- end
420
-
421
416
  def rails_app?
422
417
  defined?(::Rails) && ::Rails.respond_to?(:application)
423
418
  end
@@ -425,3 +420,4 @@ module Sidekiq
425
420
  end
426
421
 
427
422
  require "sidekiq/systemd"
423
+ require "sidekiq/metrics/tracking"