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