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