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