sidekiq 5.2.1 → 6.0.7

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.

Potentially problematic release.


This version of sidekiq might be problematic. Click here for more details.

Files changed (86) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +60 -0
  3. data/.gitignore +1 -1
  4. data/.standard.yml +20 -0
  5. data/6.0-Upgrade.md +72 -0
  6. data/COMM-LICENSE +11 -9
  7. data/Changes.md +209 -0
  8. data/Ent-2.0-Upgrade.md +37 -0
  9. data/Ent-Changes.md +36 -1
  10. data/Gemfile +19 -9
  11. data/Gemfile.lock +208 -0
  12. data/Pro-5.0-Upgrade.md +25 -0
  13. data/Pro-Changes.md +44 -1
  14. data/README.md +19 -31
  15. data/Rakefile +6 -4
  16. data/bin/sidekiq +19 -0
  17. data/bin/sidekiqload +33 -25
  18. data/bin/sidekiqmon +8 -0
  19. data/lib/generators/sidekiq/templates/worker_test.rb.erb +1 -1
  20. data/lib/generators/sidekiq/worker_generator.rb +21 -13
  21. data/lib/sidekiq/api.rb +240 -214
  22. data/lib/sidekiq/cli.rb +167 -219
  23. data/lib/sidekiq/client.rb +61 -46
  24. data/lib/sidekiq/delay.rb +5 -6
  25. data/lib/sidekiq/exception_handler.rb +10 -12
  26. data/lib/sidekiq/extensions/action_mailer.rb +10 -20
  27. data/lib/sidekiq/extensions/active_record.rb +9 -7
  28. data/lib/sidekiq/extensions/class_methods.rb +9 -7
  29. data/lib/sidekiq/extensions/generic_proxy.rb +4 -4
  30. data/lib/sidekiq/fetch.rb +11 -12
  31. data/lib/sidekiq/job_logger.rb +47 -9
  32. data/lib/sidekiq/job_retry.rb +79 -58
  33. data/lib/sidekiq/launcher.rb +86 -54
  34. data/lib/sidekiq/logger.rb +165 -0
  35. data/lib/sidekiq/manager.rb +10 -12
  36. data/lib/sidekiq/middleware/chain.rb +14 -4
  37. data/lib/sidekiq/middleware/i18n.rb +5 -7
  38. data/lib/sidekiq/monitor.rb +133 -0
  39. data/lib/sidekiq/paginator.rb +18 -14
  40. data/lib/sidekiq/processor.rb +113 -79
  41. data/lib/sidekiq/rails.rb +24 -29
  42. data/lib/sidekiq/redis_connection.rb +42 -24
  43. data/lib/sidekiq/scheduled.rb +28 -29
  44. data/lib/sidekiq/sd_notify.rb +149 -0
  45. data/lib/sidekiq/systemd.rb +24 -0
  46. data/lib/sidekiq/testing/inline.rb +2 -1
  47. data/lib/sidekiq/testing.rb +34 -23
  48. data/lib/sidekiq/util.rb +17 -16
  49. data/lib/sidekiq/version.rb +2 -1
  50. data/lib/sidekiq/web/action.rb +14 -10
  51. data/lib/sidekiq/web/application.rb +79 -69
  52. data/lib/sidekiq/web/helpers.rb +89 -71
  53. data/lib/sidekiq/web/router.rb +17 -16
  54. data/lib/sidekiq/web.rb +41 -49
  55. data/lib/sidekiq/worker.rb +134 -91
  56. data/lib/sidekiq.rb +69 -44
  57. data/sidekiq.gemspec +16 -18
  58. data/web/assets/javascripts/application.js +22 -19
  59. data/web/assets/javascripts/dashboard.js +16 -25
  60. data/web/assets/stylesheets/application-dark.css +122 -0
  61. data/web/assets/stylesheets/application.css +44 -2
  62. data/web/assets/stylesheets/bootstrap.css +1 -1
  63. data/web/locales/ar.yml +1 -0
  64. data/web/locales/de.yml +14 -2
  65. data/web/locales/en.yml +3 -0
  66. data/web/locales/fr.yml +2 -2
  67. data/web/locales/ja.yml +4 -1
  68. data/web/locales/lt.yml +83 -0
  69. data/web/locales/vi.yml +83 -0
  70. data/web/views/_job_info.erb +2 -1
  71. data/web/views/_nav.erb +3 -17
  72. data/web/views/busy.erb +4 -1
  73. data/web/views/dead.erb +2 -2
  74. data/web/views/layout.erb +1 -0
  75. data/web/views/morgue.erb +4 -1
  76. data/web/views/queue.erb +11 -1
  77. data/web/views/queues.erb +9 -1
  78. data/web/views/retries.erb +8 -1
  79. data/web/views/retry.erb +2 -2
  80. data/web/views/scheduled.erb +4 -1
  81. metadata +37 -27
  82. data/.travis.yml +0 -14
  83. data/bin/sidekiqctl +0 -99
  84. data/lib/sidekiq/core_ext.rb +0 -1
  85. data/lib/sidekiq/logging.rb +0 -122
  86. data/lib/sidekiq/middleware/server/active_record.rb +0 -23
data/lib/sidekiq/cli.rb CHANGED
@@ -1,45 +1,29 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  $stdout.sync = true
3
4
 
4
- require 'yaml'
5
- require 'singleton'
6
- require 'optparse'
7
- require 'erb'
8
- require 'fileutils'
5
+ require "yaml"
6
+ require "singleton"
7
+ require "optparse"
8
+ require "erb"
9
+ require "fileutils"
9
10
 
10
- require 'sidekiq'
11
- require 'sidekiq/util'
11
+ require "sidekiq"
12
+ require "sidekiq/launcher"
13
+ require "sidekiq/util"
12
14
 
13
15
  module Sidekiq
14
16
  class CLI
15
17
  include Util
16
18
  include Singleton unless $TESTING
17
19
 
18
- PROCTITLES = [
19
- proc { 'sidekiq' },
20
- proc { Sidekiq::VERSION },
21
- proc { |me, data| data['tag'] },
22
- proc { |me, data| "[#{Processor::WORKER_STATE.size} of #{data['concurrency']} busy]" },
23
- proc { |me, data| "stopping" if me.stopping? },
24
- ]
25
-
26
- # Used for CLI testing
27
- attr_accessor :code
28
20
  attr_accessor :launcher
29
21
  attr_accessor :environment
30
22
 
31
- def initialize
32
- @code = nil
33
- end
34
-
35
- def parse(args=ARGV)
36
- @code = nil
37
-
23
+ def parse(args = ARGV)
38
24
  setup_options(args)
39
25
  initialize_logger
40
26
  validate!
41
- daemonize
42
- write_pid
43
27
  end
44
28
 
45
29
  def jruby?
@@ -51,34 +35,31 @@ module Sidekiq
51
35
  # test coverage of Sidekiq::CLI are welcomed.
52
36
  def run
53
37
  boot_system
54
- print_banner
38
+ if environment == "development" && $stdout.tty? && Sidekiq.log_formatter.is_a?(Sidekiq::Logger::Formatters::Pretty)
39
+ print_banner
40
+ end
41
+ logger.info "Booted Rails #{::Rails.version} application in #{environment} environment" if rails_app?
55
42
 
56
43
  self_read, self_write = IO.pipe
57
- sigs = %w(INT TERM TTIN TSTP)
44
+ sigs = %w[INT TERM TTIN TSTP]
58
45
  # USR1 and USR2 don't work on the JVM
59
- if !jruby?
60
- sigs << 'USR1'
61
- sigs << 'USR2'
62
- end
63
-
46
+ sigs << "USR2" unless jruby?
64
47
  sigs.each do |sig|
65
- begin
66
- trap sig do
67
- self_write.write("#{sig}\n")
68
- end
69
- rescue ArgumentError
70
- puts "Signal #{sig} not supported"
48
+ trap sig do
49
+ self_write.puts(sig)
71
50
  end
51
+ rescue ArgumentError
52
+ puts "Signal #{sig} not supported"
72
53
  end
73
54
 
74
55
  logger.info "Running in #{RUBY_DESCRIPTION}"
75
56
  logger.info Sidekiq::LICENSE
76
- logger.info "Upgrade to Sidekiq Pro for more features and support: http://sidekiq.org" unless defined?(::Sidekiq::Pro)
57
+ logger.info "Upgrade to Sidekiq Pro for more features and support: https://sidekiq.org" unless defined?(::Sidekiq::Pro)
77
58
 
78
59
  # touch the connection pool so it is created before we
79
60
  # fire startup and start multithreading.
80
- ver = Sidekiq.redis_info['redis_version']
81
- raise "You are using Redis v#{ver}, Sidekiq requires Redis v2.8.0 or greater" if ver < '2.8'
61
+ ver = Sidekiq.redis_info["redis_version"]
62
+ raise "You are connecting to Redis v#{ver}, Sidekiq requires Redis v4.0.0 or greater" if ver < "4"
82
63
 
83
64
  # Since the user can pass us a connection pool explicitly in the initializer, we
84
65
  # need to verify the size is large enough or else Sidekiq's performance is dramatically slowed.
@@ -96,142 +77,123 @@ module Sidekiq
96
77
  # Starting here the process will now have multiple threads running.
97
78
  fire_event(:startup, reverse: false, reraise: true)
98
79
 
99
- logger.debug { "Client Middleware: #{Sidekiq.client_middleware.map(&:klass).join(', ')}" }
100
- logger.debug { "Server Middleware: #{Sidekiq.server_middleware.map(&:klass).join(', ')}" }
80
+ logger.debug { "Client Middleware: #{Sidekiq.client_middleware.map(&:klass).join(", ")}" }
81
+ logger.debug { "Server Middleware: #{Sidekiq.server_middleware.map(&:klass).join(", ")}" }
82
+
83
+ launch(self_read)
84
+ end
101
85
 
102
- if !options[:daemon]
103
- logger.info 'Starting processing, hit Ctrl-C to stop'
86
+ def launch(self_read)
87
+ if environment == "development" && $stdout.tty?
88
+ logger.info "Starting processing, hit Ctrl-C to stop"
104
89
  end
105
90
 
106
- require 'sidekiq/launcher'
107
91
  @launcher = Sidekiq::Launcher.new(options)
108
92
 
109
93
  begin
110
94
  launcher.run
111
95
 
112
- while readable_io = IO.select([self_read])
96
+ while (readable_io = IO.select([self_read]))
113
97
  signal = readable_io.first[0].gets.strip
114
98
  handle_signal(signal)
115
99
  end
116
100
  rescue Interrupt
117
- logger.info 'Shutting down'
101
+ logger.info "Shutting down"
118
102
  launcher.stop
119
- # Explicitly exit so busy Processor threads can't block
120
- # process shutdown.
121
103
  logger.info "Bye!"
104
+
105
+ # Explicitly exit so busy Processor threads won't block process shutdown.
106
+ #
107
+ # NB: slow at_exit handlers will prevent a timely exit if they take
108
+ # a while to run. If Sidekiq is getting here but the process isn't exiting,
109
+ # use the TTIN signal to determine where things are stuck.
122
110
  exit(0)
123
111
  end
124
112
  end
125
113
 
114
+ def self.w
115
+ "\e[37m"
116
+ end
117
+
118
+ def self.r
119
+ "\e[31m"
120
+ end
121
+
122
+ def self.b
123
+ "\e[30m"
124
+ end
125
+
126
+ def self.reset
127
+ "\e[0m"
128
+ end
129
+
126
130
  def self.banner
127
- %q{
128
- m,
129
- `$b
130
- .ss, $$: .,d$
131
- `$$P,d$P' .,md$P"'
132
- ,$$$$$bmmd$$$P^'
133
- .d$$$$$$$$$$P'
134
- $$^' `"^$$$' ____ _ _ _ _
135
- $: ,$$: / ___|(_) __| | ___| | _(_) __ _
136
- `b :$$ \___ \| |/ _` |/ _ \ |/ / |/ _` |
137
- $$: ___) | | (_| | __/ <| | (_| |
138
- $$ |____/|_|\__,_|\___|_|\_\_|\__, |
139
- .d$$ |_|
140
- }
131
+ %{
132
+ #{w} m,
133
+ #{w} `$b
134
+ #{w} .ss, $$: .,d$
135
+ #{w} `$$P,d$P' .,md$P"'
136
+ #{w} ,$$$$$b#{b}/#{w}md$$$P^'
137
+ #{w} .d$$$$$$#{b}/#{w}$$$P'
138
+ #{w} $$^' `"#{b}/#{w}$$$' #{r}____ _ _ _ _
139
+ #{w} $: ,$$: #{r} / ___|(_) __| | ___| | _(_) __ _
140
+ #{w} `b :$$ #{r} \\___ \\| |/ _` |/ _ \\ |/ / |/ _` |
141
+ #{w} $$: #{r} ___) | | (_| | __/ <| | (_| |
142
+ #{w} $$ #{r}|____/|_|\\__,_|\\___|_|\\_\\_|\\__, |
143
+ #{w} .d$$ #{r} |_|
144
+ #{reset}}
141
145
  end
142
146
 
143
147
  SIGNAL_HANDLERS = {
144
148
  # Ctrl-C in terminal
145
- 'INT' => ->(cli) { raise Interrupt },
149
+ "INT" => ->(cli) { raise Interrupt },
146
150
  # TERM is the signal that Sidekiq must exit.
147
151
  # Heroku sends TERM and then waits 30 seconds for process to exit.
148
- 'TERM' => ->(cli) { raise Interrupt },
149
- 'USR1' => ->(cli) {
150
- Sidekiq.logger.info "Received USR1, no longer accepting new work"
151
- cli.launcher.quiet
152
- },
153
- 'TSTP' => ->(cli) {
152
+ "TERM" => ->(cli) { raise Interrupt },
153
+ "TSTP" => ->(cli) {
154
154
  Sidekiq.logger.info "Received TSTP, no longer accepting new work"
155
155
  cli.launcher.quiet
156
156
  },
157
- 'USR2' => ->(cli) {
158
- if Sidekiq.options[:logfile]
159
- Sidekiq.logger.info "Received USR2, reopening log file"
160
- Sidekiq::Logging.reopen_logs
161
- end
162
- },
163
- 'TTIN' => ->(cli) {
157
+ "TTIN" => ->(cli) {
164
158
  Thread.list.each do |thread|
165
- Sidekiq.logger.warn "Thread TID-#{(thread.object_id ^ ::Process.pid).to_s(36)} #{thread['sidekiq_label']}"
159
+ Sidekiq.logger.warn "Thread TID-#{(thread.object_id ^ ::Process.pid).to_s(36)} #{thread.name}"
166
160
  if thread.backtrace
167
161
  Sidekiq.logger.warn thread.backtrace.join("\n")
168
162
  else
169
163
  Sidekiq.logger.warn "<no backtrace available>"
170
164
  end
171
165
  end
172
- },
166
+ }
173
167
  }
168
+ UNHANDLED_SIGNAL_HANDLER = ->(cli) { Sidekiq.logger.info "No signal handler registered, ignoring" }
169
+ SIGNAL_HANDLERS.default = UNHANDLED_SIGNAL_HANDLER
174
170
 
175
171
  def handle_signal(sig)
176
172
  Sidekiq.logger.debug "Got #{sig} signal"
177
- handy = SIGNAL_HANDLERS[sig]
178
- if handy
179
- handy.call(self)
180
- else
181
- Sidekiq.logger.info { "No signal handler for #{sig}" }
182
- end
173
+ SIGNAL_HANDLERS[sig].call(self)
183
174
  end
184
175
 
185
176
  private
186
177
 
187
178
  def print_banner
188
- # Print logo and banner for development
189
- if environment == 'development' && $stdout.tty?
190
- puts "\e[#{31}m"
191
- puts Sidekiq::CLI.banner
192
- puts "\e[0m"
193
- end
194
- end
195
-
196
- def daemonize
197
- return unless options[:daemon]
198
-
199
- raise ArgumentError, "You really should set a logfile if you're going to daemonize" unless options[:logfile]
200
- files_to_reopen = []
201
- ObjectSpace.each_object(File) do |file|
202
- files_to_reopen << file unless file.closed?
203
- end
204
-
205
- ::Process.daemon(true, true)
206
-
207
- files_to_reopen.each do |file|
208
- begin
209
- file.reopen file.path, "a+"
210
- file.sync = true
211
- rescue ::Exception
212
- end
213
- end
214
-
215
- [$stdout, $stderr].each do |io|
216
- File.open(options[:logfile], 'ab') do |f|
217
- io.reopen(f)
218
- end
219
- io.sync = true
220
- end
221
- $stdin.reopen('/dev/null')
222
-
223
- initialize_logger
179
+ puts "\e[31m"
180
+ puts Sidekiq::CLI.banner
181
+ puts "\e[0m"
224
182
  end
225
183
 
226
184
  def set_environment(cli_env)
227
- @environment = cli_env || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
185
+ # See #984 for discussion.
186
+ # APP_ENV is now the preferred ENV term since it is not tech-specific.
187
+ # Both Sinatra 2.0+ and Sidekiq support this term.
188
+ # RAILS_ENV and RACK_ENV are there for legacy support.
189
+ @environment = cli_env || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
228
190
  end
229
191
 
230
192
  def symbolize_keys_deep!(hash)
231
193
  hash.keys.each do |k|
232
194
  symkey = k.respond_to?(:to_sym) ? k.to_sym : k
233
195
  hash[symkey] = hash.delete k
234
- symbolize_keys_deep! hash[symkey] if hash[symkey].kind_of? Hash
196
+ symbolize_keys_deep! hash[symkey] if hash[symkey].is_a? Hash
235
197
  end
236
198
  end
237
199
 
@@ -239,15 +201,38 @@ module Sidekiq
239
201
  alias_method :☠, :exit
240
202
 
241
203
  def setup_options(args)
204
+ # parse CLI options
242
205
  opts = parse_options(args)
206
+
243
207
  set_environment opts[:environment]
244
208
 
245
- cfile = opts[:config_file]
246
- opts = parse_config(cfile).merge(opts) if cfile
209
+ # check config file presence
210
+ if opts[:config_file]
211
+ unless File.exist?(opts[:config_file])
212
+ raise ArgumentError, "No such file #{opts[:config_file]}"
213
+ end
214
+ else
215
+ config_dir = if File.directory?(opts[:require].to_s)
216
+ File.join(opts[:require], "config")
217
+ else
218
+ File.join(options[:require], "config")
219
+ end
247
220
 
221
+ %w[sidekiq.yml sidekiq.yml.erb].each do |config_file|
222
+ path = File.join(config_dir, config_file)
223
+ opts[:config_file] ||= path if File.exist?(path)
224
+ end
225
+ end
226
+
227
+ # parse config file options
228
+ opts = parse_config(opts[:config_file]).merge(opts) if opts[:config_file]
229
+
230
+ # set defaults
231
+ opts[:queues] = ["default"] if opts[:queues].nil? || opts[:queues].empty?
248
232
  opts[:strict] = true if opts[:strict].nil?
249
- opts[:concurrency] = Integer(ENV["RAILS_MAX_THREADS"]) if !opts[:concurrency] && ENV["RAILS_MAX_THREADS"]
233
+ opts[:concurrency] = Integer(ENV["RAILS_MAX_THREADS"]) if opts[:concurrency].nil? && ENV["RAILS_MAX_THREADS"]
250
234
 
235
+ # merge with defaults
251
236
  options.merge!(opts)
252
237
  end
253
238
 
@@ -256,41 +241,28 @@ module Sidekiq
256
241
  end
257
242
 
258
243
  def boot_system
259
- ENV['RACK_ENV'] = ENV['RAILS_ENV'] = environment
260
-
261
- raise ArgumentError, "#{options[:require]} does not exist" unless File.exist?(options[:require])
244
+ ENV["RACK_ENV"] = ENV["RAILS_ENV"] = environment
262
245
 
263
246
  if File.directory?(options[:require])
264
- require 'rails'
265
- if ::Rails::VERSION::MAJOR < 4
247
+ require "rails"
248
+ if ::Rails::VERSION::MAJOR < 5
266
249
  raise "Sidekiq no longer supports this version of Rails"
267
- elsif ::Rails::VERSION::MAJOR == 4
268
- # Painful contortions, see 1791 for discussion
269
- # No autoloading, we want to force eager load for everything.
270
- require File.expand_path("#{options[:require]}/config/application.rb")
271
- ::Rails::Application.initializer "sidekiq.eager_load" do
272
- ::Rails.application.config.eager_load = true
273
- end
274
- require 'sidekiq/rails'
275
- require File.expand_path("#{options[:require]}/config/environment.rb")
276
250
  else
277
- require 'sidekiq/rails'
251
+ require "sidekiq/rails"
278
252
  require File.expand_path("#{options[:require]}/config/environment.rb")
279
253
  end
280
254
  options[:tag] ||= default_tag
281
255
  else
282
- not_required_message = "#{options[:require]} was not required, you should use an explicit path: " +
283
- "./#{options[:require]} or /path/to/#{options[:require]}"
284
-
285
- require(options[:require]) || raise(ArgumentError, not_required_message)
256
+ require options[:require]
286
257
  end
287
258
  end
288
259
 
289
260
  def default_tag
290
261
  dir = ::Rails.root
291
262
  name = File.basename(dir)
292
- if name.to_i != 0 && prevdir = File.dirname(dir) # Capistrano release directory?
293
- if File.basename(prevdir) == 'releases'
263
+ prevdir = File.dirname(dir) # Capistrano release directory?
264
+ if name.to_i != 0 && prevdir
265
+ if File.basename(prevdir) == "releases"
294
266
  return File.basename(File.dirname(prevdir))
295
267
  end
296
268
  end
@@ -298,12 +270,10 @@ module Sidekiq
298
270
  end
299
271
 
300
272
  def validate!
301
- options[:queues] << 'default' if options[:queues].empty?
302
-
303
273
  if !File.exist?(options[:require]) ||
304
- (File.directory?(options[:require]) && !File.exist?("#{options[:require]}/config/application.rb"))
274
+ (File.directory?(options[:require]) && !File.exist?("#{options[:require]}/config/application.rb"))
305
275
  logger.info "=================================================================="
306
- logger.info " Please point sidekiq to a Rails 4/5 application or a Ruby file "
276
+ logger.info " Please point Sidekiq to a Rails application or a Ruby file "
307
277
  logger.info " to load your worker classes with -r [DIR|FILE]."
308
278
  logger.info "=================================================================="
309
279
  logger.info @parser
@@ -311,46 +281,45 @@ module Sidekiq
311
281
  end
312
282
 
313
283
  [:concurrency, :timeout].each do |opt|
314
- raise ArgumentError, "#{opt}: #{options[opt]} is not a valid value" if options.has_key?(opt) && options[opt].to_i <= 0
284
+ raise ArgumentError, "#{opt}: #{options[opt]} is not a valid value" if options.key?(opt) && options[opt].to_i <= 0
315
285
  end
316
286
  end
317
287
 
318
288
  def parse_options(argv)
319
289
  opts = {}
290
+ @parser = option_parser(opts)
291
+ @parser.parse!(argv)
292
+ opts
293
+ end
320
294
 
321
- @parser = OptionParser.new do |o|
322
- o.on '-c', '--concurrency INT', "processor threads to use" do |arg|
295
+ def option_parser(opts)
296
+ parser = OptionParser.new { |o|
297
+ o.on "-c", "--concurrency INT", "processor threads to use" do |arg|
323
298
  opts[:concurrency] = Integer(arg)
324
299
  end
325
300
 
326
- o.on '-d', '--daemon', "Daemonize process" do |arg|
327
- opts[:daemon] = arg
301
+ o.on "-d", "--daemon", "Daemonize process" do |arg|
302
+ puts "ERROR: Daemonization mode was removed in Sidekiq 6.0, please use a proper process supervisor to start and manage your services"
328
303
  end
329
304
 
330
- o.on '-e', '--environment ENV', "Application environment" do |arg|
305
+ o.on "-e", "--environment ENV", "Application environment" do |arg|
331
306
  opts[:environment] = arg
332
307
  end
333
308
 
334
- o.on '-g', '--tag TAG', "Process tag for procline" do |arg|
309
+ o.on "-g", "--tag TAG", "Process tag for procline" do |arg|
335
310
  opts[:tag] = arg
336
311
  end
337
312
 
338
- # this index remains here for backwards compatibility but none of the Sidekiq
339
- # family use this value anymore. it was used by Pro's original reliable_fetch.
340
- o.on '-i', '--index INT', "unique process index on this machine" do |arg|
341
- opts[:index] = Integer(arg.match(/\d+/)[0])
342
- end
343
-
344
313
  o.on "-q", "--queue QUEUE[,WEIGHT]", "Queues to process with optional weights" do |arg|
345
314
  queue, weight = arg.split(",")
346
315
  parse_queue opts, queue, weight
347
316
  end
348
317
 
349
- o.on '-r', '--require [PATH|DIR]', "Location of Rails application with workers or file to require" do |arg|
318
+ o.on "-r", "--require [PATH|DIR]", "Location of Rails application with workers or file to require" do |arg|
350
319
  opts[:require] = arg
351
320
  end
352
321
 
353
- o.on '-t', '--timeout NUM', "Shutdown timeout" do |arg|
322
+ o.on "-t", "--timeout NUM", "Shutdown timeout" do |arg|
354
323
  opts[:timeout] = Integer(arg)
355
324
  end
356
325
 
@@ -358,76 +327,49 @@ module Sidekiq
358
327
  opts[:verbose] = arg
359
328
  end
360
329
 
361
- o.on '-C', '--config PATH', "path to YAML config file" do |arg|
330
+ o.on "-C", "--config PATH", "path to YAML config file" do |arg|
362
331
  opts[:config_file] = arg
363
332
  end
364
333
 
365
- o.on '-L', '--logfile PATH', "path to writable logfile" do |arg|
366
- opts[:logfile] = arg
334
+ o.on "-L", "--logfile PATH", "path to writable logfile" do |arg|
335
+ puts "ERROR: Logfile redirection was removed in Sidekiq 6.0, Sidekiq will only log to STDOUT"
367
336
  end
368
337
 
369
- o.on '-P', '--pidfile PATH', "path to pidfile" do |arg|
370
- opts[:pidfile] = arg
338
+ o.on "-P", "--pidfile PATH", "path to pidfile" do |arg|
339
+ puts "ERROR: PID file creation was removed in Sidekiq 6.0, please use a proper process supervisor to start and manage your services"
371
340
  end
372
341
 
373
- o.on '-V', '--version', "Print version and exit" do |arg|
342
+ o.on "-V", "--version", "Print version and exit" do |arg|
374
343
  puts "Sidekiq #{Sidekiq::VERSION}"
375
344
  die(0)
376
345
  end
377
- end
346
+ }
378
347
 
379
- @parser.banner = "sidekiq [options]"
380
- @parser.on_tail "-h", "--help", "Show help" do
381
- logger.info @parser
348
+ parser.banner = "sidekiq [options]"
349
+ parser.on_tail "-h", "--help", "Show help" do
350
+ logger.info parser
382
351
  die 1
383
352
  end
384
- @parser.parse!(argv)
385
-
386
- %w[config/sidekiq.yml config/sidekiq.yml.erb].each do |filename|
387
- opts[:config_file] ||= filename if File.exist?(filename)
388
- end
389
353
 
390
- opts
354
+ parser
391
355
  end
392
356
 
393
357
  def initialize_logger
394
- Sidekiq::Logging.initialize_logger(options[:logfile]) if options[:logfile]
395
-
396
358
  Sidekiq.logger.level = ::Logger::DEBUG if options[:verbose]
397
359
  end
398
360
 
399
- def write_pid
400
- if path = options[:pidfile]
401
- pidfile = File.expand_path(path)
402
- File.open(pidfile, 'w') do |f|
403
- f.puts ::Process.pid
404
- end
405
- end
406
- end
407
-
408
- def parse_config(cfile)
409
- opts = {}
410
- if File.exist?(cfile)
411
- opts = YAML.load(ERB.new(IO.read(cfile)).result) || opts
412
-
413
- if opts.respond_to? :deep_symbolize_keys!
414
- opts.deep_symbolize_keys!
415
- else
416
- symbolize_keys_deep!(opts)
417
- end
361
+ def parse_config(path)
362
+ opts = YAML.load(ERB.new(File.read(path)).result) || {}
418
363
 
419
- opts = opts.merge(opts.delete(environment.to_sym) || {})
420
- parse_queues(opts, opts.delete(:queues) || [])
364
+ if opts.respond_to? :deep_symbolize_keys!
365
+ opts.deep_symbolize_keys!
421
366
  else
422
- # allow a non-existent config file so Sidekiq
423
- # can be deployed by cap with just the defaults.
424
- end
425
- ns = opts.delete(:namespace)
426
- if ns
427
- # logger hasn't been initialized yet, puts is all we have.
428
- puts("namespace should be set in your ruby initializer, is ignored in config file")
429
- puts("config.redis = { :url => ..., :namespace => '#{ns}' }")
367
+ symbolize_keys_deep!(opts)
430
368
  end
369
+
370
+ opts = opts.merge(opts.delete(environment.to_sym) || {})
371
+ parse_queues(opts, opts.delete(:queues) || [])
372
+
431
373
  opts
432
374
  end
433
375
 
@@ -435,11 +377,17 @@ module Sidekiq
435
377
  queues_and_weights.each { |queue_and_weight| parse_queue(opts, *queue_and_weight) }
436
378
  end
437
379
 
438
- def parse_queue(opts, q, weight=nil)
439
- [weight.to_i, 1].max.times do
440
- (opts[:queues] ||= []) << q
441
- end
380
+ def parse_queue(opts, queue, weight = nil)
381
+ opts[:queues] ||= []
382
+ raise ArgumentError, "queues: #{queue} cannot be defined twice" if opts[:queues].include?(queue)
383
+ [weight.to_i, 1].max.times { opts[:queues] << queue }
442
384
  opts[:strict] = false if weight.to_i > 0
443
385
  end
386
+
387
+ def rails_app?
388
+ defined?(::Rails) && ::Rails.respond_to?(:application)
389
+ end
444
390
  end
445
391
  end
392
+
393
+ require "sidekiq/systemd"