sidekiq 5.1.1 → 7.1.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.

Files changed (149) hide show
  1. checksums.yaml +5 -5
  2. data/Changes.md +627 -8
  3. data/LICENSE.txt +9 -0
  4. data/README.md +47 -50
  5. data/bin/sidekiq +22 -3
  6. data/bin/sidekiqload +213 -115
  7. data/bin/sidekiqmon +11 -0
  8. data/lib/generators/sidekiq/job_generator.rb +57 -0
  9. data/lib/generators/sidekiq/templates/{worker.rb.erb → job.rb.erb} +2 -2
  10. data/lib/generators/sidekiq/templates/{worker_spec.rb.erb → job_spec.rb.erb} +1 -1
  11. data/lib/generators/sidekiq/templates/{worker_test.rb.erb → job_test.rb.erb} +1 -1
  12. data/lib/sidekiq/api.rb +566 -329
  13. data/lib/sidekiq/capsule.rb +127 -0
  14. data/lib/sidekiq/cli.rb +241 -256
  15. data/lib/sidekiq/client.rb +125 -102
  16. data/lib/sidekiq/component.rb +68 -0
  17. data/lib/sidekiq/config.rb +278 -0
  18. data/lib/sidekiq/deploy.rb +62 -0
  19. data/lib/sidekiq/embedded.rb +61 -0
  20. data/lib/sidekiq/fetch.rb +49 -42
  21. data/lib/sidekiq/job.rb +374 -0
  22. data/lib/sidekiq/job_logger.rb +36 -9
  23. data/lib/sidekiq/job_retry.rb +147 -98
  24. data/lib/sidekiq/job_util.rb +105 -0
  25. data/lib/sidekiq/launcher.rb +207 -103
  26. data/lib/sidekiq/logger.rb +131 -0
  27. data/lib/sidekiq/manager.rb +43 -47
  28. data/lib/sidekiq/metrics/query.rb +153 -0
  29. data/lib/sidekiq/metrics/shared.rb +95 -0
  30. data/lib/sidekiq/metrics/tracking.rb +136 -0
  31. data/lib/sidekiq/middleware/chain.rb +113 -56
  32. data/lib/sidekiq/middleware/current_attributes.rb +95 -0
  33. data/lib/sidekiq/middleware/i18n.rb +7 -7
  34. data/lib/sidekiq/middleware/modules.rb +21 -0
  35. data/lib/sidekiq/monitor.rb +146 -0
  36. data/lib/sidekiq/paginator.rb +28 -16
  37. data/lib/sidekiq/processor.rb +159 -107
  38. data/lib/sidekiq/rails.rb +54 -43
  39. data/lib/sidekiq/redis_client_adapter.rb +96 -0
  40. data/lib/sidekiq/redis_connection.rb +39 -81
  41. data/lib/sidekiq/ring_buffer.rb +29 -0
  42. data/lib/sidekiq/scheduled.rb +139 -48
  43. data/lib/sidekiq/sd_notify.rb +149 -0
  44. data/lib/sidekiq/systemd.rb +24 -0
  45. data/lib/sidekiq/testing/inline.rb +6 -5
  46. data/lib/sidekiq/testing.rb +70 -88
  47. data/lib/sidekiq/transaction_aware_client.rb +44 -0
  48. data/lib/sidekiq/version.rb +3 -1
  49. data/lib/sidekiq/web/action.rb +15 -11
  50. data/lib/sidekiq/web/application.rb +143 -77
  51. data/lib/sidekiq/web/csrf_protection.rb +180 -0
  52. data/lib/sidekiq/web/helpers.rb +144 -106
  53. data/lib/sidekiq/web/router.rb +23 -19
  54. data/lib/sidekiq/web.rb +60 -111
  55. data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
  56. data/lib/sidekiq.rb +94 -183
  57. data/sidekiq.gemspec +25 -23
  58. data/web/assets/images/apple-touch-icon.png +0 -0
  59. data/web/assets/javascripts/application.js +130 -61
  60. data/web/assets/javascripts/base-charts.js +106 -0
  61. data/web/assets/javascripts/chart.min.js +13 -0
  62. data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
  63. data/web/assets/javascripts/dashboard-charts.js +166 -0
  64. data/web/assets/javascripts/dashboard.js +36 -282
  65. data/web/assets/javascripts/metrics.js +264 -0
  66. data/web/assets/stylesheets/application-dark.css +147 -0
  67. data/web/assets/stylesheets/application-rtl.css +2 -95
  68. data/web/assets/stylesheets/application.css +134 -521
  69. data/web/assets/stylesheets/bootstrap.css +2 -2
  70. data/web/locales/ar.yml +71 -64
  71. data/web/locales/cs.yml +62 -62
  72. data/web/locales/da.yml +60 -53
  73. data/web/locales/de.yml +65 -53
  74. data/web/locales/el.yml +43 -24
  75. data/web/locales/en.yml +84 -65
  76. data/web/locales/es.yml +70 -54
  77. data/web/locales/fa.yml +65 -65
  78. data/web/locales/fr.yml +83 -62
  79. data/web/locales/gd.yml +99 -0
  80. data/web/locales/he.yml +65 -64
  81. data/web/locales/hi.yml +59 -59
  82. data/web/locales/it.yml +53 -53
  83. data/web/locales/ja.yml +75 -64
  84. data/web/locales/ko.yml +52 -52
  85. data/web/locales/lt.yml +83 -0
  86. data/web/locales/nb.yml +61 -61
  87. data/web/locales/nl.yml +52 -52
  88. data/web/locales/pl.yml +45 -45
  89. data/web/locales/pt-br.yml +63 -55
  90. data/web/locales/pt.yml +51 -51
  91. data/web/locales/ru.yml +68 -63
  92. data/web/locales/sv.yml +53 -53
  93. data/web/locales/ta.yml +60 -60
  94. data/web/locales/uk.yml +62 -61
  95. data/web/locales/ur.yml +64 -64
  96. data/web/locales/vi.yml +83 -0
  97. data/web/locales/zh-cn.yml +43 -16
  98. data/web/locales/zh-tw.yml +42 -8
  99. data/web/views/_footer.erb +8 -2
  100. data/web/views/_job_info.erb +21 -4
  101. data/web/views/_metrics_period_select.erb +12 -0
  102. data/web/views/_nav.erb +4 -18
  103. data/web/views/_paging.erb +2 -0
  104. data/web/views/_poll_link.erb +3 -6
  105. data/web/views/_summary.erb +7 -7
  106. data/web/views/busy.erb +75 -25
  107. data/web/views/dashboard.erb +58 -18
  108. data/web/views/dead.erb +3 -3
  109. data/web/views/layout.erb +4 -2
  110. data/web/views/metrics.erb +82 -0
  111. data/web/views/metrics_for_job.erb +68 -0
  112. data/web/views/morgue.erb +14 -15
  113. data/web/views/queue.erb +33 -23
  114. data/web/views/queues.erb +14 -4
  115. data/web/views/retries.erb +19 -16
  116. data/web/views/retry.erb +3 -3
  117. data/web/views/scheduled.erb +17 -15
  118. metadata +71 -140
  119. data/.github/contributing.md +0 -32
  120. data/.github/issue_template.md +0 -11
  121. data/.gitignore +0 -13
  122. data/.travis.yml +0 -14
  123. data/3.0-Upgrade.md +0 -70
  124. data/4.0-Upgrade.md +0 -53
  125. data/5.0-Upgrade.md +0 -56
  126. data/COMM-LICENSE +0 -95
  127. data/Ent-Changes.md +0 -210
  128. data/Gemfile +0 -8
  129. data/LICENSE +0 -9
  130. data/Pro-2.0-Upgrade.md +0 -138
  131. data/Pro-3.0-Upgrade.md +0 -44
  132. data/Pro-4.0-Upgrade.md +0 -35
  133. data/Pro-Changes.md +0 -716
  134. data/Rakefile +0 -8
  135. data/bin/sidekiqctl +0 -99
  136. data/code_of_conduct.md +0 -50
  137. data/lib/generators/sidekiq/worker_generator.rb +0 -49
  138. data/lib/sidekiq/core_ext.rb +0 -1
  139. data/lib/sidekiq/delay.rb +0 -41
  140. data/lib/sidekiq/exception_handler.rb +0 -29
  141. data/lib/sidekiq/extensions/action_mailer.rb +0 -57
  142. data/lib/sidekiq/extensions/active_record.rb +0 -40
  143. data/lib/sidekiq/extensions/class_methods.rb +0 -40
  144. data/lib/sidekiq/extensions/generic_proxy.rb +0 -31
  145. data/lib/sidekiq/logging.rb +0 -122
  146. data/lib/sidekiq/middleware/server/active_record.rb +0 -22
  147. data/lib/sidekiq/middleware/server/active_record_cache.rb +0 -11
  148. data/lib/sidekiq/util.rb +0 -66
  149. data/lib/sidekiq/worker.rb +0 -204
data/lib/sidekiq/web.rb CHANGED
@@ -1,36 +1,37 @@
1
1
  # frozen_string_literal: true
2
- require 'erb'
3
2
 
4
- require 'sidekiq'
5
- require 'sidekiq/api'
6
- require 'sidekiq/paginator'
7
- require 'sidekiq/web/helpers'
3
+ require "erb"
8
4
 
9
- require 'sidekiq/web/router'
10
- require 'sidekiq/web/action'
11
- require 'sidekiq/web/application'
5
+ require "sidekiq"
6
+ require "sidekiq/api"
7
+ require "sidekiq/paginator"
8
+ require "sidekiq/web/helpers"
12
9
 
13
- require 'rack/protection'
10
+ require "sidekiq/web/router"
11
+ require "sidekiq/web/action"
12
+ require "sidekiq/web/application"
13
+ require "sidekiq/web/csrf_protection"
14
14
 
15
- require 'rack/builder'
16
- require 'rack/file'
17
- require 'rack/session/cookie'
15
+ require "rack/content_length"
16
+ require "rack/builder"
17
+ require "rack/static"
18
18
 
19
19
  module Sidekiq
20
20
  class Web
21
21
  ROOT = File.expand_path("#{File.dirname(__FILE__)}/../../web")
22
- VIEWS = "#{ROOT}/views".freeze
23
- LOCALES = ["#{ROOT}/locales".freeze]
24
- LAYOUT = "#{VIEWS}/layout.erb".freeze
25
- ASSETS = "#{ROOT}/assets".freeze
22
+ VIEWS = "#{ROOT}/views"
23
+ LOCALES = ["#{ROOT}/locales"]
24
+ LAYOUT = "#{VIEWS}/layout.erb"
25
+ ASSETS = "#{ROOT}/assets"
26
26
 
27
27
  DEFAULT_TABS = {
28
- "Dashboard" => '',
29
- "Busy" => 'busy',
30
- "Queues" => 'queues',
31
- "Retries" => 'retries',
32
- "Scheduled" => 'scheduled',
33
- "Dead" => 'morgue',
28
+ "Dashboard" => "",
29
+ "Busy" => "busy",
30
+ "Queues" => "queues",
31
+ "Retries" => "retries",
32
+ "Scheduled" => "scheduled",
33
+ "Dead" => "morgue",
34
+ "Metrics" => "metrics"
34
35
  }
35
36
 
36
37
  class << self
@@ -38,14 +39,6 @@ module Sidekiq
38
39
  self
39
40
  end
40
41
 
41
- def middlewares
42
- @middlewares ||= []
43
- end
44
-
45
- def use(*middleware_args, &block)
46
- middlewares << [middleware_args, block]
47
- end
48
-
49
42
  def default_tabs
50
43
  DEFAULT_TABS
51
44
  end
@@ -55,6 +48,10 @@ module Sidekiq
55
48
  end
56
49
  alias_method :tabs, :custom_tabs
57
50
 
51
+ def custom_job_info_rows
52
+ @custom_job_info_rows ||= []
53
+ end
54
+
58
55
  def locales
59
56
  @locales ||= LOCALES
60
57
  end
@@ -64,39 +61,44 @@ module Sidekiq
64
61
  end
65
62
 
66
63
  def enable(*opts)
67
- opts.each {|key| set(key, true) }
64
+ opts.each { |key| set(key, true) }
68
65
  end
69
66
 
70
67
  def disable(*opts)
71
- opts.each {|key| set(key, false) }
68
+ opts.each { |key| set(key, false) }
69
+ end
70
+
71
+ def middlewares
72
+ @middlewares ||= []
73
+ end
74
+
75
+ def use(*args, &block)
76
+ middlewares << [args, block]
72
77
  end
73
78
 
74
- # Helper for the Sinatra syntax: Sidekiq::Web.set(:session_secret, Rails.application.secrets...)
75
79
  def set(attribute, value)
76
80
  send(:"#{attribute}=", value)
77
81
  end
78
82
 
79
- attr_accessor :app_url, :session_secret, :redis_pool, :sessions
83
+ attr_accessor :app_url, :redis_pool
80
84
  attr_writer :locales, :views
81
85
  end
82
86
 
83
87
  def self.inherited(child)
84
- child.app_url = self.app_url
85
- child.session_secret = self.session_secret
86
- child.redis_pool = self.redis_pool
87
- child.sessions = self.sessions
88
+ child.app_url = app_url
89
+ child.redis_pool = redis_pool
88
90
  end
89
91
 
90
92
  def settings
91
93
  self.class.settings
92
94
  end
93
95
 
94
- def use(*middleware_args, &block)
95
- middlewares << [middleware_args, block]
96
+ def middlewares
97
+ @middlewares ||= self.class.middlewares
96
98
  end
97
99
 
98
- def middlewares
99
- @middlewares ||= Web.middlewares.dup
100
+ def use(*args, &block)
101
+ middlewares << [args, block]
100
102
  end
101
103
 
102
104
  def call(env)
@@ -113,81 +115,37 @@ module Sidekiq
113
115
  end
114
116
 
115
117
  def enable(*opts)
116
- opts.each {|key| set(key, true) }
118
+ opts.each { |key| set(key, true) }
117
119
  end
118
120
 
119
121
  def disable(*opts)
120
- opts.each {|key| set(key, false) }
122
+ opts.each { |key| set(key, false) }
121
123
  end
122
124
 
123
125
  def set(attribute, value)
124
126
  send(:"#{attribute}=", value)
125
127
  end
126
128
 
127
- # Default values
128
- set :sessions, true
129
-
130
- attr_writer :sessions
131
-
132
- def sessions
133
- unless instance_variable_defined?("@sessions")
134
- @sessions = self.class.sessions
135
- @sessions = @sessions.to_hash.dup if @sessions.respond_to?(:to_hash)
136
- end
137
-
138
- @sessions
139
- end
140
-
141
129
  def self.register(extension)
142
130
  extension.registered(WebApplication)
143
131
  end
144
132
 
145
133
  private
146
134
 
147
- def using?(middleware)
148
- middlewares.any? do |(m,_)|
149
- m.kind_of?(Array) && (m[0] == middleware || m[0].kind_of?(middleware))
150
- end
151
- end
152
-
153
- def build_sessions
154
- middlewares = self.middlewares
155
-
156
- unless using?(::Rack::Protection) || ENV['RACK_ENV'] == 'test'
157
- middlewares.unshift [[::Rack::Protection, { use: :authenticity_token }], nil]
158
- end
159
-
160
- s = sessions
161
- return unless s
162
-
163
- unless using? ::Rack::Session::Cookie
164
- unless secret = Web.session_secret
165
- require 'securerandom'
166
- secret = SecureRandom.hex(64)
167
- end
168
-
169
- options = { secret: secret }
170
- options = options.merge(s.to_hash) if s.respond_to? :to_hash
171
-
172
- middlewares.unshift [[::Rack::Session::Cookie, options], nil]
173
- end
174
- end
175
-
176
135
  def build
177
- build_sessions
178
-
179
- middlewares = self.middlewares
180
136
  klass = self.class
137
+ m = middlewares
181
138
 
182
- ::Rack::Builder.new do
183
- %w(stylesheets javascripts images).each do |asset_dir|
184
- map "/#{asset_dir}" do
185
- run ::Rack::File.new("#{ASSETS}/#{asset_dir}", { 'Cache-Control' => 'public, max-age=86400' })
186
- end
187
- end
188
-
189
- middlewares.each {|middleware, block| use(*middleware, &block) }
139
+ rules = []
140
+ rules = [[:all, {"Cache-Control" => "private, max-age=86400"}]] unless ENV["SIDEKIQ_WEB_TESTING"]
190
141
 
142
+ ::Rack::Builder.new do
143
+ use Rack::Static, urls: ["/stylesheets", "/images", "/javascripts"],
144
+ root: ASSETS,
145
+ cascade: true,
146
+ header_rules: rules
147
+ m.each { |middleware, block| use(*middleware, &block) }
148
+ use Sidekiq::Web::CsrfProtection unless $TESTING
191
149
  run WebApplication.new(klass)
192
150
  end
193
151
  end
@@ -196,18 +154,9 @@ module Sidekiq
196
154
  Sidekiq::WebApplication.helpers WebHelpers
197
155
  Sidekiq::WebApplication.helpers Sidekiq::Paginator
198
156
 
199
- Sidekiq::WebAction.class_eval "def _render\n#{ERB.new(File.read(Web::LAYOUT)).src}\nend"
200
- end
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)
157
+ Sidekiq::WebAction.class_eval <<-RUBY, __FILE__, __LINE__ + 1
158
+ def _render
159
+ #{ERB.new(File.read(Web::LAYOUT)).src}
211
160
  end
212
- end
161
+ RUBY
213
162
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sidekiq
4
+ # Sidekiq::Job is a new alias for Sidekiq::Worker as of Sidekiq 6.3.0.
5
+ # Use `include Sidekiq::Job` rather than `include Sidekiq::Worker`.
6
+ #
7
+ # The term "worker" is too generic and overly confusing, used in several
8
+ # different contexts meaning different things. Many people call a Sidekiq
9
+ # process a "worker". Some people call the thread that executes jobs a
10
+ # "worker". This change brings Sidekiq closer to ActiveJob where your job
11
+ # classes extend ApplicationJob.
12
+ Worker = Job
13
+ end
data/lib/sidekiq.rb CHANGED
@@ -1,236 +1,147 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
- require 'sidekiq/version'
4
- fail "Sidekiq #{Sidekiq::VERSION} does not support Ruby versions below 2.2.2." if RUBY_PLATFORM != 'java' && RUBY_VERSION < '2.2.2'
5
2
 
6
- require 'sidekiq/logging'
7
- require 'sidekiq/client'
8
- require 'sidekiq/worker'
9
- require 'sidekiq/redis_connection'
10
- require 'sidekiq/delay'
3
+ require "sidekiq/version"
4
+ fail "Sidekiq #{Sidekiq::VERSION} does not support Ruby versions below 2.7.0." if RUBY_PLATFORM != "java" && Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.7.0")
11
5
 
12
- require 'json'
6
+ begin
7
+ require "sidekiq-ent/version"
8
+ fail <<~EOM if Gem::Version.new(Sidekiq::Enterprise::VERSION).segments[0] != Sidekiq::MAJOR
13
9
 
14
- module Sidekiq
15
- NAME = 'Sidekiq'.freeze
16
- LICENSE = 'See LICENSE and the LGPL-3.0 for licensing details.'
17
-
18
- DEFAULTS = {
19
- queues: [],
20
- labels: [],
21
- concurrency: 25,
22
- require: '.',
23
- environment: nil,
24
- timeout: 8,
25
- poll_interval_average: nil,
26
- average_scheduled_poll_interval: 5,
27
- error_handlers: [],
28
- death_handlers: [],
29
- lifecycle_events: {
30
- startup: [],
31
- quiet: [],
32
- shutdown: [],
33
- heartbeat: [],
34
- },
35
- dead_max_jobs: 10_000,
36
- dead_timeout_in_seconds: 180 * 24 * 60 * 60, # 6 months
37
- reloader: proc { |&block| block.call },
38
- }
39
-
40
- DEFAULT_WORKER_OPTIONS = {
41
- 'retry' => true,
42
- 'queue' => 'default'
43
- }
44
-
45
- FAKE_INFO = {
46
- "redis_version" => "9.9.9",
47
- "uptime_in_days" => "9999",
48
- "connected_clients" => "9999",
49
- "used_memory_human" => "9P",
50
- "used_memory_peak_human" => "9P"
51
- }.freeze
10
+ Sidekiq Enterprise #{Sidekiq::Enterprise::VERSION} does not work with Sidekiq #{Sidekiq::VERSION}.
11
+ Starting with Sidekiq 7, major versions are synchronized so Sidekiq Enterprise 7 works with Sidekiq 7.
12
+ Use `bundle up sidekiq-ent` to upgrade.
52
13
 
53
- def self.❨╯°□°❩╯︵┻━┻
54
- puts "Calm down, yo."
55
- end
14
+ EOM
15
+ rescue LoadError
16
+ end
56
17
 
57
- def self.options
58
- @options ||= DEFAULTS.dup
59
- end
60
- def self.options=(opts)
61
- @options = opts
62
- end
18
+ begin
19
+ require "sidekiq/pro/version"
20
+ fail <<~EOM if Gem::Version.new(Sidekiq::Pro::VERSION).segments[0] != Sidekiq::MAJOR
63
21
 
64
- ##
65
- # Configuration for Sidekiq server, use like:
66
- #
67
- # Sidekiq.configure_server do |config|
68
- # config.redis = { :namespace => 'myapp', :size => 25, :url => 'redis://myhost:8877/0' }
69
- # config.server_middleware do |chain|
70
- # chain.add MyServerHook
71
- # end
72
- # end
73
- def self.configure_server
74
- yield self if server?
75
- end
22
+ Sidekiq Pro #{Sidekiq::Pro::VERSION} does not work with Sidekiq #{Sidekiq::VERSION}.
23
+ Starting with Sidekiq 7, major versions are synchronized so Sidekiq Pro 7 works with Sidekiq 7.
24
+ Use `bundle up sidekiq-pro` to upgrade.
76
25
 
77
- ##
78
- # Configuration for Sidekiq client, use like:
79
- #
80
- # Sidekiq.configure_client do |config|
81
- # config.redis = { :namespace => 'myapp', :size => 1, :url => 'redis://myhost:8877/0' }
82
- # end
83
- def self.configure_client
84
- yield self unless server?
26
+ EOM
27
+ rescue LoadError
28
+ end
29
+
30
+ require "sidekiq/config"
31
+ require "sidekiq/logger"
32
+ require "sidekiq/client"
33
+ require "sidekiq/transaction_aware_client"
34
+ require "sidekiq/job"
35
+ require "sidekiq/worker_compatibility_alias"
36
+ require "sidekiq/redis_client_adapter"
37
+
38
+ require "json"
39
+
40
+ module Sidekiq
41
+ NAME = "Sidekiq"
42
+ LICENSE = "See LICENSE and the LGPL-3.0 for licensing details."
43
+
44
+ def self.❨╯°□°❩╯︵┻━┻
45
+ puts "Take a deep breath and count to ten..."
85
46
  end
86
47
 
87
48
  def self.server?
88
49
  defined?(Sidekiq::CLI)
89
50
  end
90
51
 
91
- def self.redis
92
- raise ArgumentError, "requires a block" unless block_given?
93
- redis_pool.with do |conn|
94
- retryable = true
95
- begin
96
- yield conn
97
- rescue Redis::CommandError => ex
98
- #2550 Failover can cause the server to become a slave, need
99
- # to disconnect and reopen the socket to get back to the master.
100
- (conn.disconnect!; retryable = false; retry) if retryable && ex.message =~ /READONLY/
101
- raise
102
- end
103
- end
104
- end
105
-
106
- def self.redis_info
107
- redis do |conn|
108
- begin
109
- # admin commands can't go through redis-namespace starting
110
- # in redis-namespace 2.0
111
- if conn.respond_to?(:namespace)
112
- conn.redis.info
113
- else
114
- conn.info
115
- end
116
- rescue Redis::CommandError => ex
117
- #2850 return fake version when INFO command has (probably) been renamed
118
- raise unless ex.message =~ /unknown command/
119
- FAKE_INFO
120
- end
121
- end
52
+ def self.load_json(string)
53
+ JSON.parse(string)
122
54
  end
123
55
 
124
- def self.redis_pool
125
- @redis ||= Sidekiq::RedisConnection.create
56
+ def self.dump_json(object)
57
+ JSON.generate(object)
126
58
  end
127
59
 
128
- def self.redis=(hash)
129
- @redis = if hash.is_a?(ConnectionPool)
130
- hash
131
- else
132
- Sidekiq::RedisConnection.create(hash)
133
- end
60
+ def self.pro?
61
+ defined?(Sidekiq::Pro)
134
62
  end
135
63
 
136
- def self.client_middleware
137
- @client_chain ||= Middleware::Chain.new
138
- yield @client_chain if block_given?
139
- @client_chain
64
+ def self.ent?
65
+ defined?(Sidekiq::Enterprise)
140
66
  end
141
67
 
142
- def self.server_middleware
143
- @server_chain ||= default_server_middleware
144
- yield @server_chain if block_given?
145
- @server_chain
68
+ def self.redis_pool
69
+ (Thread.current[:sidekiq_capsule] || default_configuration).redis_pool
146
70
  end
147
71
 
148
- def self.default_server_middleware
149
- Middleware::Chain.new
72
+ def self.redis(&block)
73
+ (Thread.current[:sidekiq_capsule] || default_configuration).redis(&block)
150
74
  end
151
75
 
152
- def self.default_worker_options=(hash)
153
- # stringify
154
- @default_worker_options = default_worker_options.merge(Hash[hash.map{|k, v| [k.to_s, v]}])
155
- end
156
- def self.default_worker_options
157
- defined?(@default_worker_options) ? @default_worker_options : DEFAULT_WORKER_OPTIONS
76
+ def self.strict_args!(mode = :raise)
77
+ Sidekiq::Config::DEFAULTS[:on_complex_arguments] = mode
158
78
  end
159
79
 
160
- def self.default_retries_exhausted=(prok)
161
- logger.info { "default_retries_exhausted is deprecated, please use `config.death_handlers << -> {|job, ex| }`" }
162
- return nil unless prok
163
- death_handlers << prok
80
+ def self.default_job_options=(hash)
81
+ @default_job_options = default_job_options.merge(hash.transform_keys(&:to_s))
164
82
  end
165
83
 
166
- ##
167
- # Death handlers are called when all retries for a job have been exhausted and
168
- # the job dies. It's the notification to your application
169
- # that this job will not succeed without manual intervention.
170
- #
171
- # Sidekiq.configure_server do |config|
172
- # config.death_handlers << ->(job, ex) do
173
- # end
174
- # end
175
- def self.death_handlers
176
- options[:death_handlers]
84
+ def self.default_job_options
85
+ @default_job_options ||= {"retry" => true, "queue" => "default"}
177
86
  end
178
87
 
179
- def self.load_json(string)
180
- JSON.parse(string)
181
- end
182
- def self.dump_json(object)
183
- JSON.generate(object)
88
+ def self.default_configuration
89
+ @config ||= Sidekiq::Config.new
184
90
  end
185
91
 
186
92
  def self.logger
187
- Sidekiq::Logging.logger
93
+ default_configuration.logger
188
94
  end
189
- def self.logger=(log)
190
- Sidekiq::Logging.logger = log
95
+
96
+ def self.configure_server(&block)
97
+ (@config_blocks ||= []) << block
98
+ yield default_configuration if server?
191
99
  end
192
100
 
193
- # How frequently Redis should be checked by a random Sidekiq process for
194
- # scheduled and retriable jobs. Each individual process will take turns by
195
- # waiting some multiple of this value.
196
- #
197
- # See sidekiq/scheduled.rb for an in-depth explanation of this value
198
- def self.average_scheduled_poll_interval=(interval)
199
- self.options[:average_scheduled_poll_interval] = interval
101
+ def self.freeze!
102
+ @frozen = true
103
+ @config_blocks = nil
200
104
  end
201
105
 
202
- # Register a proc to handle any error which occurs within the Sidekiq process.
106
+ # Creates a Sidekiq::Config instance that is more tuned for embedding
107
+ # within an arbitrary Ruby process. Notably it reduces concurrency by
108
+ # default so there is less contention for CPU time with other threads.
203
109
  #
204
- # Sidekiq.configure_server do |config|
205
- # config.error_handlers << proc {|ex,ctx_hash| MyErrorService.notify(ex, ctx_hash) }
110
+ # inst = Sidekiq.configure_embed do |config|
111
+ # config.queues = %w[critical default low]
206
112
  # end
113
+ # inst.run
114
+ # sleep 10
115
+ # inst.terminate
116
+ #
117
+ # NB: it is really easy to overload a Ruby process with threads due to the GIL.
118
+ # I do not recommend setting concurrency higher than 2-3.
207
119
  #
208
- # The default error handler logs errors to Sidekiq.logger.
209
- def self.error_handlers
210
- self.options[:error_handlers]
120
+ # NB: Sidekiq only supports one instance in memory. You will get undefined behavior
121
+ # if you try to embed Sidekiq twice in the same process.
122
+ def self.configure_embed(&block)
123
+ raise "Sidekiq global configuration is frozen, you must create all embedded instances BEFORE calling `run`" if @frozen
124
+
125
+ require "sidekiq/embedded"
126
+ cfg = default_configuration
127
+ cfg.concurrency = 2
128
+ @config_blocks&.each { |block| block.call(cfg) }
129
+ yield cfg
130
+
131
+ Sidekiq::Embedded.new(cfg)
211
132
  end
212
133
 
213
- # Register a block to run at a point in the Sidekiq lifecycle.
214
- # :startup, :quiet or :shutdown are valid events.
215
- #
216
- # Sidekiq.configure_server do |config|
217
- # config.on(:shutdown) do
218
- # puts "Goodbye cruel world!"
219
- # end
220
- # end
221
- def self.on(event, &block)
222
- raise ArgumentError, "Symbols only please: #{event}" unless event.is_a?(Symbol)
223
- raise ArgumentError, "Invalid event name: #{event}" unless options[:lifecycle_events].key?(event)
224
- options[:lifecycle_events][event] << block
134
+ def self.configure_client
135
+ yield default_configuration unless server?
225
136
  end
226
137
 
227
- # We are shutting down Sidekiq but what about workers that
138
+ # We are shutting down Sidekiq but what about threads that
228
139
  # are working on some long job? This error is
229
- # raised in workers that have not finished within the hard
140
+ # raised in jobs that have not finished within the hard
230
141
  # timeout limit. This is needed to rollback db transactions,
231
142
  # otherwise Ruby's Thread#kill will commit. See #377.
232
- # DO NOT RESCUE THIS ERROR IN YOUR WORKERS
143
+ # DO NOT RESCUE THIS ERROR IN YOUR JOBS
233
144
  class Shutdown < Interrupt; end
234
145
  end
235
146
 
236
- require 'sidekiq/rails' if defined?(::Rails::Engine)
147
+ require "sidekiq/rails" if defined?(::Rails::Engine)
data/sidekiq.gemspec CHANGED
@@ -1,28 +1,30 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/sidekiq/version', __FILE__)
1
+ require_relative "lib/sidekiq/version"
3
2
 
4
3
  Gem::Specification.new do |gem|
5
- gem.authors = ["Mike Perham"]
6
- gem.email = ["mperham@gmail.com"]
7
- gem.summary = "Simple, efficient background processing for Ruby"
8
- gem.description = "Simple, efficient background processing for Ruby."
9
- gem.homepage = "http://sidekiq.org"
10
- gem.license = "LGPL-3.0"
4
+ gem.authors = ["Mike Perham"]
5
+ gem.email = ["info@contribsys.com"]
6
+ gem.summary = "Simple, efficient background processing for Ruby"
7
+ gem.description = "Simple, efficient background processing for Ruby."
8
+ gem.homepage = "https://sidekiq.org"
9
+ gem.license = "LGPL-3.0"
11
10
 
12
- gem.executables = ['sidekiq', 'sidekiqctl']
13
- gem.files = `git ls-files | grep -Ev '^(test|myapp|examples)'`.split("\n")
14
- gem.test_files = []
15
- gem.name = "sidekiq"
16
- gem.require_paths = ["lib"]
17
- gem.version = Sidekiq::VERSION
18
- gem.required_ruby_version = ">= 2.2.2"
11
+ gem.executables = ["sidekiq", "sidekiqmon"]
12
+ gem.files = %w[sidekiq.gemspec README.md Changes.md LICENSE.txt] + `git ls-files | grep -E '^(bin|lib|web)'`.split("\n")
13
+ gem.name = "sidekiq"
14
+ gem.version = Sidekiq::VERSION
15
+ gem.required_ruby_version = ">= 2.7.0"
19
16
 
20
- gem.add_dependency 'redis', '>= 3.3.5', '< 5'
21
- gem.add_dependency 'connection_pool', '~> 2.2', '>= 2.2.0'
22
- gem.add_dependency 'concurrent-ruby', '~> 1.0'
23
- gem.add_dependency 'rack-protection', '>= 1.5.0'
24
- gem.add_development_dependency 'redis-namespace', '~> 1.5', '>= 1.5.2'
25
- gem.add_development_dependency 'minitest', '~> 5.10', '>= 5.10.1'
26
- gem.add_development_dependency 'rake', '~> 10.0'
27
- gem.add_development_dependency 'rails', '>= 3.2.0'
17
+ gem.metadata = {
18
+ "homepage_uri" => "https://sidekiq.org",
19
+ "bug_tracker_uri" => "https://github.com/sidekiq/sidekiq/issues",
20
+ "documentation_uri" => "https://github.com/sidekiq/sidekiq/wiki",
21
+ "changelog_uri" => "https://github.com/sidekiq/sidekiq/blob/main/Changes.md",
22
+ "source_code_uri" => "https://github.com/sidekiq/sidekiq",
23
+ "rubygems_mfa_required" => "true"
24
+ }
25
+
26
+ gem.add_dependency "redis-client", ">= 0.14.0"
27
+ gem.add_dependency "connection_pool", ">= 2.3.0"
28
+ gem.add_dependency "rack", ">= 2.2.4"
29
+ gem.add_dependency "concurrent-ruby", "< 2"
28
30
  end