sidekiq 5.2.8 → 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 +4 -4
- data/.gitignore +0 -2
- data/.standard.yml +20 -0
- data/6.0-Upgrade.md +70 -0
- data/Changes.md +31 -3
- data/Ent-2.0-Upgrade.md +37 -0
- data/Ent-Changes.md +12 -0
- data/Gemfile +12 -11
- data/Gemfile.lock +196 -0
- data/Pro-5.0-Upgrade.md +25 -0
- data/Pro-Changes.md +12 -3
- data/README.md +16 -30
- data/Rakefile +5 -4
- data/bin/sidekiqload +26 -22
- data/bin/sidekiqmon +9 -0
- data/lib/generators/sidekiq/templates/worker_test.rb.erb +1 -1
- data/lib/generators/sidekiq/worker_generator.rb +12 -14
- data/lib/sidekiq/api.rb +138 -151
- data/lib/sidekiq/cli.rb +97 -162
- data/lib/sidekiq/client.rb +45 -46
- data/lib/sidekiq/delay.rb +5 -6
- data/lib/sidekiq/exception_handler.rb +10 -12
- 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 +37 -7
- data/lib/sidekiq/job_retry.rb +45 -58
- data/lib/sidekiq/launcher.rb +59 -51
- data/lib/sidekiq/logger.rb +69 -0
- data/lib/sidekiq/manager.rb +7 -9
- 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 +52 -49
- data/lib/sidekiq/rails.rb +23 -29
- data/lib/sidekiq/redis_connection.rb +31 -37
- data/lib/sidekiq/scheduled.rb +17 -19
- data/lib/sidekiq/testing/inline.rb +2 -1
- data/lib/sidekiq/testing.rb +22 -23
- data/lib/sidekiq/util.rb +17 -14
- data/lib/sidekiq/version.rb +2 -1
- data/lib/sidekiq/web/action.rb +14 -10
- data/lib/sidekiq/web/application.rb +60 -57
- data/lib/sidekiq/web/helpers.rb +66 -67
- data/lib/sidekiq/web/router.rb +17 -14
- data/lib/sidekiq/web.rb +41 -49
- data/lib/sidekiq/worker.rb +124 -97
- data/lib/sidekiq.rb +53 -42
- data/sidekiq.gemspec +16 -16
- data/web/assets/javascripts/dashboard.js +2 -21
- data/web/locales/ja.yml +2 -1
- metadata +21 -31
- data/.travis.yml +0 -11
- data/bin/sidekiqctl +0 -20
- 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/web.rb
CHANGED
@@ -1,20 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require 'erb'
|
3
2
|
|
4
|
-
require
|
5
|
-
require 'sidekiq/api'
|
6
|
-
require 'sidekiq/paginator'
|
7
|
-
require 'sidekiq/web/helpers'
|
3
|
+
require "erb"
|
8
4
|
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
5
|
+
require "sidekiq"
|
6
|
+
require "sidekiq/api"
|
7
|
+
require "sidekiq/paginator"
|
8
|
+
require "sidekiq/web/helpers"
|
12
9
|
|
13
|
-
require
|
10
|
+
require "sidekiq/web/router"
|
11
|
+
require "sidekiq/web/action"
|
12
|
+
require "sidekiq/web/application"
|
14
13
|
|
15
|
-
require
|
16
|
-
|
17
|
-
require
|
14
|
+
require "rack/protection"
|
15
|
+
|
16
|
+
require "rack/builder"
|
17
|
+
require "rack/file"
|
18
|
+
require "rack/session/cookie"
|
18
19
|
|
19
20
|
module Sidekiq
|
20
21
|
class Web
|
@@ -25,12 +26,12 @@ module Sidekiq
|
|
25
26
|
ASSETS = "#{ROOT}/assets"
|
26
27
|
|
27
28
|
DEFAULT_TABS = {
|
28
|
-
"Dashboard" =>
|
29
|
-
"Busy"
|
30
|
-
"Queues"
|
31
|
-
"Retries"
|
32
|
-
"Scheduled" =>
|
33
|
-
"Dead"
|
29
|
+
"Dashboard" => "",
|
30
|
+
"Busy" => "busy",
|
31
|
+
"Queues" => "queues",
|
32
|
+
"Retries" => "retries",
|
33
|
+
"Scheduled" => "scheduled",
|
34
|
+
"Dead" => "morgue",
|
34
35
|
}
|
35
36
|
|
36
37
|
class << self
|
@@ -64,11 +65,11 @@ module Sidekiq
|
|
64
65
|
end
|
65
66
|
|
66
67
|
def enable(*opts)
|
67
|
-
opts.each {|key| set(key, true) }
|
68
|
+
opts.each { |key| set(key, true) }
|
68
69
|
end
|
69
70
|
|
70
71
|
def disable(*opts)
|
71
|
-
opts.each {|key| set(key, false) }
|
72
|
+
opts.each { |key| set(key, false) }
|
72
73
|
end
|
73
74
|
|
74
75
|
# Helper for the Sinatra syntax: Sidekiq::Web.set(:session_secret, Rails.application.secrets...)
|
@@ -81,10 +82,10 @@ module Sidekiq
|
|
81
82
|
end
|
82
83
|
|
83
84
|
def self.inherited(child)
|
84
|
-
child.app_url =
|
85
|
-
child.session_secret =
|
86
|
-
child.redis_pool =
|
87
|
-
child.sessions =
|
85
|
+
child.app_url = app_url
|
86
|
+
child.session_secret = session_secret
|
87
|
+
child.redis_pool = redis_pool
|
88
|
+
child.sessions = sessions
|
88
89
|
end
|
89
90
|
|
90
91
|
def settings
|
@@ -113,11 +114,11 @@ module Sidekiq
|
|
113
114
|
end
|
114
115
|
|
115
116
|
def enable(*opts)
|
116
|
-
opts.each {|key| set(key, true) }
|
117
|
+
opts.each { |key| set(key, true) }
|
117
118
|
end
|
118
119
|
|
119
120
|
def disable(*opts)
|
120
|
-
opts.each {|key| set(key, false) }
|
121
|
+
opts.each { |key| set(key, false) }
|
121
122
|
end
|
122
123
|
|
123
124
|
def set(attribute, value)
|
@@ -145,28 +146,28 @@ module Sidekiq
|
|
145
146
|
private
|
146
147
|
|
147
148
|
def using?(middleware)
|
148
|
-
middlewares.any? do |(m,_)|
|
149
|
-
m.
|
149
|
+
middlewares.any? do |(m, _)|
|
150
|
+
m.is_a?(Array) && (m[0] == middleware || m[0].is_a?(middleware))
|
150
151
|
end
|
151
152
|
end
|
152
153
|
|
153
154
|
def build_sessions
|
154
155
|
middlewares = self.middlewares
|
155
156
|
|
156
|
-
unless using?(::Rack::Protection) || ENV[
|
157
|
-
middlewares.unshift [[::Rack::Protection, {
|
157
|
+
unless using?(::Rack::Protection) || ENV["RACK_ENV"] == "test"
|
158
|
+
middlewares.unshift [[::Rack::Protection, {use: :authenticity_token}], nil]
|
158
159
|
end
|
159
160
|
|
160
161
|
s = sessions
|
161
162
|
return unless s
|
162
163
|
|
163
164
|
unless using? ::Rack::Session::Cookie
|
164
|
-
unless secret = Web.session_secret
|
165
|
-
require
|
165
|
+
unless (secret = Web.session_secret)
|
166
|
+
require "securerandom"
|
166
167
|
secret = SecureRandom.hex(64)
|
167
168
|
end
|
168
169
|
|
169
|
-
options = {
|
170
|
+
options = {secret: secret}
|
170
171
|
options = options.merge(s.to_hash) if s.respond_to? :to_hash
|
171
172
|
|
172
173
|
middlewares.unshift [[::Rack::Session::Cookie, options], nil]
|
@@ -180,13 +181,13 @@ module Sidekiq
|
|
180
181
|
klass = self.class
|
181
182
|
|
182
183
|
::Rack::Builder.new do
|
183
|
-
%w
|
184
|
+
%w[stylesheets javascripts images].each do |asset_dir|
|
184
185
|
map "/#{asset_dir}" do
|
185
|
-
run ::Rack::File.new("#{ASSETS}/#{asset_dir}", {
|
186
|
+
run ::Rack::File.new("#{ASSETS}/#{asset_dir}", {"Cache-Control" => "public, max-age=86400"})
|
186
187
|
end
|
187
188
|
end
|
188
189
|
|
189
|
-
middlewares.each {|middleware, block| use(*middleware, &block) }
|
190
|
+
middlewares.each { |middleware, block| use(*middleware, &block) }
|
190
191
|
|
191
192
|
run WebApplication.new(klass)
|
192
193
|
end
|
@@ -196,18 +197,9 @@ module Sidekiq
|
|
196
197
|
Sidekiq::WebApplication.helpers WebHelpers
|
197
198
|
Sidekiq::WebApplication.helpers Sidekiq::Paginator
|
198
199
|
|
199
|
-
Sidekiq::WebAction.class_eval
|
200
|
-
|
201
|
-
|
202
|
-
if defined?(::ActionDispatch::Request::Session) &&
|
203
|
-
!::ActionDispatch::Request::Session.method_defined?(:each)
|
204
|
-
# mperham/sidekiq#2460
|
205
|
-
# Rack apps can't reuse the Rails session store without
|
206
|
-
# this monkeypatch, fixed in Rails 5.
|
207
|
-
class ActionDispatch::Request::Session
|
208
|
-
def each(&block)
|
209
|
-
hash = self.to_hash
|
210
|
-
hash.each(&block)
|
200
|
+
Sidekiq::WebAction.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
201
|
+
def _render
|
202
|
+
#{ERB.new(File.read(Web::LAYOUT)).src}
|
211
203
|
end
|
212
|
-
|
204
|
+
RUBY
|
213
205
|
end
|
data/lib/sidekiq/worker.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require 'sidekiq/client'
|
3
2
|
|
4
|
-
|
3
|
+
require "sidekiq/client"
|
5
4
|
|
5
|
+
module Sidekiq
|
6
6
|
##
|
7
7
|
# Include this module in your worker class and you can easily create
|
8
8
|
# asynchronous jobs:
|
@@ -21,15 +21,124 @@ module Sidekiq
|
|
21
21
|
#
|
22
22
|
# Note that perform_async is a class method, perform is an instance method.
|
23
23
|
module Worker
|
24
|
+
##
|
25
|
+
# The Options module is extracted so we can include it in ActiveJob::Base
|
26
|
+
# and allow native AJs to configure Sidekiq features/internals.
|
27
|
+
module Options
|
28
|
+
def self.included(base)
|
29
|
+
base.extend(ClassMethods)
|
30
|
+
base.sidekiq_class_attribute :sidekiq_options_hash
|
31
|
+
base.sidekiq_class_attribute :sidekiq_retry_in_block
|
32
|
+
base.sidekiq_class_attribute :sidekiq_retries_exhausted_block
|
33
|
+
end
|
34
|
+
|
35
|
+
module ClassMethods
|
36
|
+
ACCESSOR_MUTEX = Mutex.new
|
37
|
+
|
38
|
+
##
|
39
|
+
# Allows customization for this type of Worker.
|
40
|
+
# Legal options:
|
41
|
+
#
|
42
|
+
# queue - name of queue to use for this job type, default *default*
|
43
|
+
# retry - enable retries for this Worker in case of error during execution,
|
44
|
+
# *true* to use the default or *Integer* count
|
45
|
+
# backtrace - whether to save any error backtrace in the retry payload to display in web UI,
|
46
|
+
# can be true, false or an integer number of lines to save, default *false*
|
47
|
+
#
|
48
|
+
# In practice, any option is allowed. This is the main mechanism to configure the
|
49
|
+
# options for a specific job.
|
50
|
+
def sidekiq_options(opts = {})
|
51
|
+
opts = Hash[opts.map { |k, v| [k.to_s, v] }] # stringify
|
52
|
+
self.sidekiq_options_hash = get_sidekiq_options.merge(Hash[opts.map { |k, v| [k.to_s, v] }])
|
53
|
+
end
|
54
|
+
|
55
|
+
def sidekiq_retry_in(&block)
|
56
|
+
self.sidekiq_retry_in_block = block
|
57
|
+
end
|
58
|
+
|
59
|
+
def sidekiq_retries_exhausted(&block)
|
60
|
+
self.sidekiq_retries_exhausted_block = block
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_sidekiq_options # :nodoc:
|
64
|
+
self.sidekiq_options_hash ||= Sidekiq.default_worker_options
|
65
|
+
end
|
66
|
+
|
67
|
+
def sidekiq_class_attribute(*attrs)
|
68
|
+
instance_reader = true
|
69
|
+
instance_writer = true
|
70
|
+
|
71
|
+
attrs.each do |name|
|
72
|
+
synchronized_getter = "__synchronized_#{name}"
|
73
|
+
|
74
|
+
singleton_class.instance_eval do
|
75
|
+
undef_method(name) if method_defined?(name) || private_method_defined?(name)
|
76
|
+
end
|
77
|
+
|
78
|
+
define_singleton_method(synchronized_getter) { nil }
|
79
|
+
singleton_class.class_eval do
|
80
|
+
private(synchronized_getter)
|
81
|
+
end
|
82
|
+
|
83
|
+
define_singleton_method(name) { ACCESSOR_MUTEX.synchronize { send synchronized_getter } }
|
84
|
+
|
85
|
+
ivar = "@#{name}"
|
86
|
+
|
87
|
+
singleton_class.instance_eval do
|
88
|
+
m = "#{name}="
|
89
|
+
undef_method(m) if method_defined?(m) || private_method_defined?(m)
|
90
|
+
end
|
91
|
+
define_singleton_method("#{name}=") do |val|
|
92
|
+
singleton_class.class_eval do
|
93
|
+
ACCESSOR_MUTEX.synchronize do
|
94
|
+
undef_method(synchronized_getter) if method_defined?(synchronized_getter) || private_method_defined?(synchronized_getter)
|
95
|
+
define_method(synchronized_getter) { val }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
if singleton_class?
|
100
|
+
class_eval do
|
101
|
+
undef_method(name) if method_defined?(name) || private_method_defined?(name)
|
102
|
+
define_method(name) do
|
103
|
+
if instance_variable_defined? ivar
|
104
|
+
instance_variable_get ivar
|
105
|
+
else
|
106
|
+
singleton_class.send name
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
val
|
112
|
+
end
|
113
|
+
|
114
|
+
if instance_reader
|
115
|
+
undef_method(name) if method_defined?(name) || private_method_defined?(name)
|
116
|
+
define_method(name) do
|
117
|
+
if instance_variable_defined?(ivar)
|
118
|
+
instance_variable_get ivar
|
119
|
+
else
|
120
|
+
self.class.public_send name
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
if instance_writer
|
126
|
+
m = "#{name}="
|
127
|
+
undef_method(m) if method_defined?(m) || private_method_defined?(m)
|
128
|
+
attr_writer name
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
24
135
|
attr_accessor :jid
|
25
136
|
|
26
137
|
def self.included(base)
|
27
|
-
raise ArgumentError, "
|
138
|
+
raise ArgumentError, "Sidekiq::Worker cannot be included in an ActiveJob: #{base.name}" if base.ancestors.any? { |c| c.name == "ActiveJob::Base" }
|
28
139
|
|
140
|
+
base.include(Options)
|
29
141
|
base.extend(ClassMethods)
|
30
|
-
base.sidekiq_class_attribute :sidekiq_options_hash
|
31
|
-
base.sidekiq_class_attribute :sidekiq_retry_in_block
|
32
|
-
base.sidekiq_class_attribute :sidekiq_retries_exhausted_block
|
33
142
|
end
|
34
143
|
|
35
144
|
def logger
|
@@ -52,7 +161,7 @@ module Sidekiq
|
|
52
161
|
end
|
53
162
|
|
54
163
|
def perform_async(*args)
|
55
|
-
@klass.client_push(@opts.merge(
|
164
|
+
@klass.client_push(@opts.merge("args" => args, "class" => @klass))
|
56
165
|
end
|
57
166
|
|
58
167
|
# +interval+ must be a timestamp, numeric or something that acts
|
@@ -62,17 +171,15 @@ module Sidekiq
|
|
62
171
|
now = Time.now.to_f
|
63
172
|
ts = (int < 1_000_000_000 ? now + int : int)
|
64
173
|
|
65
|
-
payload = @opts.merge(
|
174
|
+
payload = @opts.merge("class" => @klass, "args" => args, "at" => ts)
|
66
175
|
# Optimization to enqueue something now that is scheduled to go out now or in the past
|
67
|
-
payload.delete(
|
176
|
+
payload.delete("at") if ts <= now
|
68
177
|
@klass.client_push(payload)
|
69
178
|
end
|
70
179
|
alias_method :perform_at, :perform_in
|
71
180
|
end
|
72
181
|
|
73
182
|
module ClassMethods
|
74
|
-
ACCESSOR_MUTEX = Mutex.new
|
75
|
-
|
76
183
|
def delay(*args)
|
77
184
|
raise ArgumentError, "Do not call .delay on a Sidekiq::Worker class, call .perform_async"
|
78
185
|
end
|
@@ -90,7 +197,7 @@ module Sidekiq
|
|
90
197
|
end
|
91
198
|
|
92
199
|
def perform_async(*args)
|
93
|
-
client_push(
|
200
|
+
client_push("class" => self, "args" => args)
|
94
201
|
end
|
95
202
|
|
96
203
|
# +interval+ must be a timestamp, numeric or something that acts
|
@@ -100,10 +207,10 @@ module Sidekiq
|
|
100
207
|
now = Time.now.to_f
|
101
208
|
ts = (int < 1_000_000_000 ? now + int : int)
|
102
209
|
|
103
|
-
item = {
|
210
|
+
item = {"class" => self, "args" => args, "at" => ts}
|
104
211
|
|
105
212
|
# Optimization to enqueue something now that is scheduled to go out now or in the past
|
106
|
-
item.delete(
|
213
|
+
item.delete("at") if ts <= now
|
107
214
|
|
108
215
|
client_push(item)
|
109
216
|
end
|
@@ -122,25 +229,12 @@ module Sidekiq
|
|
122
229
|
#
|
123
230
|
# In practice, any option is allowed. This is the main mechanism to configure the
|
124
231
|
# options for a specific job.
|
125
|
-
def sidekiq_options(opts={})
|
126
|
-
|
127
|
-
self.sidekiq_options_hash = get_sidekiq_options.merge(Hash[opts.map{|k, v| [k.to_s, v]}])
|
128
|
-
end
|
129
|
-
|
130
|
-
def sidekiq_retry_in(&block)
|
131
|
-
self.sidekiq_retry_in_block = block
|
132
|
-
end
|
133
|
-
|
134
|
-
def sidekiq_retries_exhausted(&block)
|
135
|
-
self.sidekiq_retries_exhausted_block = block
|
136
|
-
end
|
137
|
-
|
138
|
-
def get_sidekiq_options # :nodoc:
|
139
|
-
self.sidekiq_options_hash ||= Sidekiq.default_worker_options
|
232
|
+
def sidekiq_options(opts = {})
|
233
|
+
super
|
140
234
|
end
|
141
235
|
|
142
236
|
def client_push(item) # :nodoc:
|
143
|
-
pool = Thread.current[:sidekiq_via_pool] || get_sidekiq_options[
|
237
|
+
pool = Thread.current[:sidekiq_via_pool] || get_sidekiq_options["pool"] || Sidekiq.redis_pool
|
144
238
|
# stringify
|
145
239
|
item.keys.each do |key|
|
146
240
|
item[key.to_s] = item.delete(key)
|
@@ -148,73 +242,6 @@ module Sidekiq
|
|
148
242
|
|
149
243
|
Sidekiq::Client.new(pool).push(item)
|
150
244
|
end
|
151
|
-
|
152
|
-
def sidekiq_class_attribute(*attrs)
|
153
|
-
instance_reader = true
|
154
|
-
instance_writer = true
|
155
|
-
|
156
|
-
attrs.each do |name|
|
157
|
-
synchronized_getter = "__synchronized_#{name}"
|
158
|
-
|
159
|
-
singleton_class.instance_eval do
|
160
|
-
undef_method(name) if method_defined?(name) || private_method_defined?(name)
|
161
|
-
end
|
162
|
-
|
163
|
-
define_singleton_method(synchronized_getter) { nil }
|
164
|
-
singleton_class.class_eval do
|
165
|
-
private(synchronized_getter)
|
166
|
-
end
|
167
|
-
|
168
|
-
define_singleton_method(name) { ACCESSOR_MUTEX.synchronize { send synchronized_getter } }
|
169
|
-
|
170
|
-
ivar = "@#{name}"
|
171
|
-
|
172
|
-
singleton_class.instance_eval do
|
173
|
-
m = "#{name}="
|
174
|
-
undef_method(m) if method_defined?(m) || private_method_defined?(m)
|
175
|
-
end
|
176
|
-
define_singleton_method("#{name}=") do |val|
|
177
|
-
singleton_class.class_eval do
|
178
|
-
ACCESSOR_MUTEX.synchronize do
|
179
|
-
undef_method(synchronized_getter) if method_defined?(synchronized_getter) || private_method_defined?(synchronized_getter)
|
180
|
-
define_method(synchronized_getter) { val }
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
if singleton_class?
|
185
|
-
class_eval do
|
186
|
-
undef_method(name) if method_defined?(name) || private_method_defined?(name)
|
187
|
-
define_method(name) do
|
188
|
-
if instance_variable_defined? ivar
|
189
|
-
instance_variable_get ivar
|
190
|
-
else
|
191
|
-
singleton_class.send name
|
192
|
-
end
|
193
|
-
end
|
194
|
-
end
|
195
|
-
end
|
196
|
-
val
|
197
|
-
end
|
198
|
-
|
199
|
-
if instance_reader
|
200
|
-
undef_method(name) if method_defined?(name) || private_method_defined?(name)
|
201
|
-
define_method(name) do
|
202
|
-
if instance_variable_defined?(ivar)
|
203
|
-
instance_variable_get ivar
|
204
|
-
else
|
205
|
-
self.class.public_send name
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
if instance_writer
|
211
|
-
m = "#{name}="
|
212
|
-
undef_method(m) if method_defined?(m) || private_method_defined?(m)
|
213
|
-
attr_writer name
|
214
|
-
end
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
245
|
end
|
219
246
|
end
|
220
247
|
end
|
data/lib/sidekiq.rb
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
fail "Sidekiq #{Sidekiq::VERSION} does not support Ruby versions below 2.
|
3
|
+
require "sidekiq/version"
|
4
|
+
fail "Sidekiq #{Sidekiq::VERSION} does not support Ruby versions below 2.5.0." if RUBY_PLATFORM != "java" && Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.5.0")
|
5
5
|
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
6
|
+
require "sidekiq/logger"
|
7
|
+
require "sidekiq/client"
|
8
|
+
require "sidekiq/worker"
|
9
|
+
require "sidekiq/redis_connection"
|
10
|
+
require "sidekiq/delay"
|
11
11
|
|
12
|
-
require
|
12
|
+
require "json"
|
13
13
|
|
14
14
|
module Sidekiq
|
15
|
-
NAME =
|
16
|
-
LICENSE =
|
15
|
+
NAME = "Sidekiq"
|
16
|
+
LICENSE = "See LICENSE and the LGPL-3.0 for licensing details."
|
17
17
|
|
18
18
|
DEFAULTS = {
|
19
19
|
queues: [],
|
20
20
|
labels: [],
|
21
21
|
concurrency: 10,
|
22
|
-
require:
|
22
|
+
require: ".",
|
23
23
|
environment: nil,
|
24
|
-
timeout:
|
24
|
+
timeout: 25,
|
25
25
|
poll_interval_average: nil,
|
26
26
|
average_scheduled_poll_interval: 5,
|
27
27
|
error_handlers: [],
|
@@ -38,8 +38,8 @@ module Sidekiq
|
|
38
38
|
}
|
39
39
|
|
40
40
|
DEFAULT_WORKER_OPTIONS = {
|
41
|
-
|
42
|
-
|
41
|
+
"retry" => true,
|
42
|
+
"queue" => "default",
|
43
43
|
}
|
44
44
|
|
45
45
|
FAKE_INFO = {
|
@@ -47,7 +47,7 @@ module Sidekiq
|
|
47
47
|
"uptime_in_days" => "9999",
|
48
48
|
"connected_clients" => "9999",
|
49
49
|
"used_memory_human" => "9P",
|
50
|
-
"used_memory_peak_human" => "9P"
|
50
|
+
"used_memory_peak_human" => "9P",
|
51
51
|
}
|
52
52
|
|
53
53
|
def self.❨╯°□°❩╯︵┻━┻
|
@@ -96,9 +96,13 @@ module Sidekiq
|
|
96
96
|
begin
|
97
97
|
yield conn
|
98
98
|
rescue Redis::CommandError => ex
|
99
|
-
#2550 Failover can cause the server to become a replica, need
|
99
|
+
# 2550 Failover can cause the server to become a replica, need
|
100
100
|
# to disconnect and reopen the socket to get back to the primary.
|
101
|
-
|
101
|
+
if retryable && ex.message =~ /READONLY/
|
102
|
+
conn.disconnect!
|
103
|
+
retryable = false
|
104
|
+
retry
|
105
|
+
end
|
102
106
|
raise
|
103
107
|
end
|
104
108
|
end
|
@@ -106,19 +110,17 @@ module Sidekiq
|
|
106
110
|
|
107
111
|
def self.redis_info
|
108
112
|
redis do |conn|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
conn.info
|
116
|
-
end
|
117
|
-
rescue Redis::CommandError => ex
|
118
|
-
#2850 return fake version when INFO command has (probably) been renamed
|
119
|
-
raise unless ex.message =~ /unknown command/
|
120
|
-
FAKE_INFO
|
113
|
+
# admin commands can't go through redis-namespace starting
|
114
|
+
# in redis-namespace 2.0
|
115
|
+
if conn.respond_to?(:namespace)
|
116
|
+
conn.redis.info
|
117
|
+
else
|
118
|
+
conn.info
|
121
119
|
end
|
120
|
+
rescue Redis::CommandError => ex
|
121
|
+
# 2850 return fake version when INFO command has (probably) been renamed
|
122
|
+
raise unless /unknown command/.match?(ex.message)
|
123
|
+
FAKE_INFO
|
122
124
|
end
|
123
125
|
end
|
124
126
|
|
@@ -152,18 +154,13 @@ module Sidekiq
|
|
152
154
|
|
153
155
|
def self.default_worker_options=(hash)
|
154
156
|
# stringify
|
155
|
-
@default_worker_options = default_worker_options.merge(Hash[hash.map{|k, v| [k.to_s, v]}])
|
157
|
+
@default_worker_options = default_worker_options.merge(Hash[hash.map { |k, v| [k.to_s, v] }])
|
156
158
|
end
|
159
|
+
|
157
160
|
def self.default_worker_options
|
158
161
|
defined?(@default_worker_options) ? @default_worker_options : DEFAULT_WORKER_OPTIONS
|
159
162
|
end
|
160
163
|
|
161
|
-
def self.default_retries_exhausted=(prok)
|
162
|
-
logger.info { "default_retries_exhausted is deprecated, please use `config.death_handlers << -> {|job, ex| }`" }
|
163
|
-
return nil unless prok
|
164
|
-
death_handlers << prok
|
165
|
-
end
|
166
|
-
|
167
164
|
##
|
168
165
|
# Death handlers are called when all retries for a job have been exhausted and
|
169
166
|
# the job dies. It's the notification to your application
|
@@ -180,15 +177,29 @@ module Sidekiq
|
|
180
177
|
def self.load_json(string)
|
181
178
|
JSON.parse(string)
|
182
179
|
end
|
180
|
+
|
183
181
|
def self.dump_json(object)
|
184
182
|
JSON.generate(object)
|
185
183
|
end
|
186
184
|
|
185
|
+
def self.log_formatter
|
186
|
+
@log_formatter ||= if ENV["DYNO"]
|
187
|
+
Sidekiq::Logger::Formatters::WithoutTimestamp.new
|
188
|
+
else
|
189
|
+
Sidekiq::Logger::Formatters::Pretty.new
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def self.log_formatter=(log_formatter)
|
194
|
+
@log_formatter = log_formatter
|
195
|
+
end
|
196
|
+
|
187
197
|
def self.logger
|
188
|
-
Sidekiq::
|
198
|
+
@logger ||= Sidekiq::Logger.new(STDOUT, level: Logger::INFO)
|
189
199
|
end
|
190
|
-
|
191
|
-
|
200
|
+
|
201
|
+
def self.logger=(logger)
|
202
|
+
@logger = logger
|
192
203
|
end
|
193
204
|
|
194
205
|
# How frequently Redis should be checked by a random Sidekiq process for
|
@@ -197,7 +208,7 @@ module Sidekiq
|
|
197
208
|
#
|
198
209
|
# See sidekiq/scheduled.rb for an in-depth explanation of this value
|
199
210
|
def self.average_scheduled_poll_interval=(interval)
|
200
|
-
|
211
|
+
options[:average_scheduled_poll_interval] = interval
|
201
212
|
end
|
202
213
|
|
203
214
|
# Register a proc to handle any error which occurs within the Sidekiq process.
|
@@ -208,7 +219,7 @@ module Sidekiq
|
|
208
219
|
#
|
209
220
|
# The default error handler logs errors to Sidekiq.logger.
|
210
221
|
def self.error_handlers
|
211
|
-
|
222
|
+
options[:error_handlers]
|
212
223
|
end
|
213
224
|
|
214
225
|
# Register a block to run at a point in the Sidekiq lifecycle.
|
@@ -234,4 +245,4 @@ module Sidekiq
|
|
234
245
|
class Shutdown < Interrupt; end
|
235
246
|
end
|
236
247
|
|
237
|
-
require
|
248
|
+
require "sidekiq/rails" if defined?(::Rails::Engine)
|
data/sidekiq.gemspec
CHANGED
@@ -1,21 +1,21 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "lib/sidekiq/version"
|
2
2
|
|
3
3
|
Gem::Specification.new do |gem|
|
4
|
-
gem.authors
|
5
|
-
gem.email
|
6
|
-
gem.summary
|
7
|
-
gem.description
|
8
|
-
gem.homepage
|
9
|
-
gem.license
|
4
|
+
gem.authors = ["Mike Perham"]
|
5
|
+
gem.email = ["mperham@gmail.com"]
|
6
|
+
gem.summary = "Simple, efficient background processing for Ruby"
|
7
|
+
gem.description = "Simple, efficient background processing for Ruby."
|
8
|
+
gem.homepage = "http://sidekiq.org"
|
9
|
+
gem.license = "LGPL-3.0"
|
10
10
|
|
11
|
-
gem.executables
|
12
|
-
gem.files
|
13
|
-
gem.name
|
14
|
-
gem.version
|
15
|
-
gem.required_ruby_version = ">= 2.
|
11
|
+
gem.executables = ["sidekiq"]
|
12
|
+
gem.files = `git ls-files | grep -Ev '^(test|myapp|examples)'`.split("\n")
|
13
|
+
gem.name = "sidekiq"
|
14
|
+
gem.version = Sidekiq::VERSION
|
15
|
+
gem.required_ruby_version = ">= 2.5.0"
|
16
16
|
|
17
|
-
gem.add_dependency
|
18
|
-
gem.add_dependency
|
19
|
-
gem.add_dependency
|
20
|
-
gem.add_dependency
|
17
|
+
gem.add_dependency "redis", ">= 4.1.0"
|
18
|
+
gem.add_dependency "connection_pool", ">= 2.2.2"
|
19
|
+
gem.add_dependency "rack", ">= 2.0.0"
|
20
|
+
gem.add_dependency "rack-protection", ">= 2.0.0"
|
21
21
|
end
|