sidekiq 5.2.2 → 7.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. checksums.yaml +5 -5
  2. data/Changes.md +657 -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 +558 -353
  13. data/lib/sidekiq/capsule.rb +127 -0
  14. data/lib/sidekiq/cli.rb +238 -260
  15. data/lib/sidekiq/client.rb +127 -102
  16. data/lib/sidekiq/component.rb +68 -0
  17. data/lib/sidekiq/config.rb +287 -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 +35 -9
  23. data/lib/sidekiq/job_retry.rb +162 -102
  24. data/lib/sidekiq/job_util.rb +107 -0
  25. data/lib/sidekiq/launcher.rb +203 -105
  26. data/lib/sidekiq/logger.rb +131 -0
  27. data/lib/sidekiq/manager.rb +43 -46
  28. data/lib/sidekiq/metrics/query.rb +155 -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 +127 -118
  38. data/lib/sidekiq/rails.rb +50 -39
  39. data/lib/sidekiq/redis_client_adapter.rb +111 -0
  40. data/lib/sidekiq/redis_connection.rb +40 -89
  41. data/lib/sidekiq/ring_buffer.rb +29 -0
  42. data/lib/sidekiq/scheduled.rb +111 -49
  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 +90 -89
  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 +189 -79
  51. data/lib/sidekiq/web/csrf_protection.rb +180 -0
  52. data/lib/sidekiq/web/helpers.rb +160 -114
  53. data/lib/sidekiq/web/router.rb +23 -19
  54. data/lib/sidekiq/web.rb +68 -107
  55. data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
  56. data/lib/sidekiq.rb +94 -182
  57. data/sidekiq.gemspec +25 -18
  58. data/web/assets/images/apple-touch-icon.png +0 -0
  59. data/web/assets/javascripts/application.js +146 -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 +182 -0
  64. data/web/assets/javascripts/dashboard.js +35 -283
  65. data/web/assets/javascripts/metrics.js +298 -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 +143 -521
  69. data/web/assets/stylesheets/bootstrap.css +1 -1
  70. data/web/locales/ar.yml +71 -65
  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 +86 -66
  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 +83 -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 +6 -3
  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 +77 -27
  107. data/web/views/dashboard.erb +48 -18
  108. data/web/views/dead.erb +3 -3
  109. data/web/views/filtering.erb +7 -0
  110. data/web/views/layout.erb +3 -1
  111. data/web/views/metrics.erb +91 -0
  112. data/web/views/metrics_for_job.erb +59 -0
  113. data/web/views/morgue.erb +14 -15
  114. data/web/views/queue.erb +33 -24
  115. data/web/views/queues.erb +19 -5
  116. data/web/views/retries.erb +16 -17
  117. data/web/views/retry.erb +3 -3
  118. data/web/views/scheduled.erb +17 -15
  119. metadata +80 -65
  120. data/.github/contributing.md +0 -32
  121. data/.github/issue_template.md +0 -11
  122. data/.gitignore +0 -13
  123. data/.travis.yml +0 -14
  124. data/3.0-Upgrade.md +0 -70
  125. data/4.0-Upgrade.md +0 -53
  126. data/5.0-Upgrade.md +0 -56
  127. data/COMM-LICENSE +0 -95
  128. data/Ent-Changes.md +0 -221
  129. data/Gemfile +0 -14
  130. data/LICENSE +0 -9
  131. data/Pro-2.0-Upgrade.md +0 -138
  132. data/Pro-3.0-Upgrade.md +0 -44
  133. data/Pro-4.0-Upgrade.md +0 -35
  134. data/Pro-Changes.md +0 -746
  135. data/Rakefile +0 -8
  136. data/bin/sidekiqctl +0 -99
  137. data/code_of_conduct.md +0 -50
  138. data/lib/generators/sidekiq/worker_generator.rb +0 -49
  139. data/lib/sidekiq/core_ext.rb +0 -1
  140. data/lib/sidekiq/delay.rb +0 -42
  141. data/lib/sidekiq/exception_handler.rb +0 -29
  142. data/lib/sidekiq/extensions/action_mailer.rb +0 -57
  143. data/lib/sidekiq/extensions/active_record.rb +0 -40
  144. data/lib/sidekiq/extensions/class_methods.rb +0 -40
  145. data/lib/sidekiq/extensions/generic_proxy.rb +0 -31
  146. data/lib/sidekiq/logging.rb +0 -122
  147. data/lib/sidekiq/middleware/server/active_record.rb +0 -23
  148. data/lib/sidekiq/util.rb +0 -66
  149. data/lib/sidekiq/worker.rb +0 -204
data/lib/sidekiq/web.rb CHANGED
@@ -1,20 +1,20 @@
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
@@ -25,27 +25,32 @@ module Sidekiq
25
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
 
37
+ if Gem::Version.new(Rack::RELEASE) < Gem::Version.new("3")
38
+ CONTENT_LANGUAGE = "Content-Language"
39
+ CONTENT_SECURITY_POLICY = "Content-Security-Policy"
40
+ LOCATION = "Location"
41
+ X_CASCADE = "X-Cascade"
42
+ else
43
+ CONTENT_LANGUAGE = "content-language"
44
+ CONTENT_SECURITY_POLICY = "content-security-policy"
45
+ LOCATION = "location"
46
+ X_CASCADE = "x-cascade"
47
+ end
48
+
36
49
  class << self
37
50
  def settings
38
51
  self
39
52
  end
40
53
 
41
- def middlewares
42
- @middlewares ||= []
43
- end
44
-
45
- def use(*middleware_args, &block)
46
- middlewares << [middleware_args, block]
47
- end
48
-
49
54
  def default_tabs
50
55
  DEFAULT_TABS
51
56
  end
@@ -55,6 +60,10 @@ module Sidekiq
55
60
  end
56
61
  alias_method :tabs, :custom_tabs
57
62
 
63
+ def custom_job_info_rows
64
+ @custom_job_info_rows ||= []
65
+ end
66
+
58
67
  def locales
59
68
  @locales ||= LOCALES
60
69
  end
@@ -64,39 +73,44 @@ module Sidekiq
64
73
  end
65
74
 
66
75
  def enable(*opts)
67
- opts.each {|key| set(key, true) }
76
+ opts.each { |key| set(key, true) }
68
77
  end
69
78
 
70
79
  def disable(*opts)
71
- opts.each {|key| set(key, false) }
80
+ opts.each { |key| set(key, false) }
81
+ end
82
+
83
+ def middlewares
84
+ @middlewares ||= []
85
+ end
86
+
87
+ def use(*args, &block)
88
+ middlewares << [args, block]
72
89
  end
73
90
 
74
- # Helper for the Sinatra syntax: Sidekiq::Web.set(:session_secret, Rails.application.secrets...)
75
91
  def set(attribute, value)
76
92
  send(:"#{attribute}=", value)
77
93
  end
78
94
 
79
- attr_accessor :app_url, :session_secret, :redis_pool, :sessions
95
+ attr_accessor :app_url, :redis_pool
80
96
  attr_writer :locales, :views
81
97
  end
82
98
 
83
99
  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
100
+ child.app_url = app_url
101
+ child.redis_pool = redis_pool
88
102
  end
89
103
 
90
104
  def settings
91
105
  self.class.settings
92
106
  end
93
107
 
94
- def use(*middleware_args, &block)
95
- middlewares << [middleware_args, block]
108
+ def middlewares
109
+ @middlewares ||= self.class.middlewares
96
110
  end
97
111
 
98
- def middlewares
99
- @middlewares ||= Web.middlewares.dup
112
+ def use(*args, &block)
113
+ middlewares << [args, block]
100
114
  end
101
115
 
102
116
  def call(env)
@@ -113,81 +127,37 @@ module Sidekiq
113
127
  end
114
128
 
115
129
  def enable(*opts)
116
- opts.each {|key| set(key, true) }
130
+ opts.each { |key| set(key, true) }
117
131
  end
118
132
 
119
133
  def disable(*opts)
120
- opts.each {|key| set(key, false) }
134
+ opts.each { |key| set(key, false) }
121
135
  end
122
136
 
123
137
  def set(attribute, value)
124
138
  send(:"#{attribute}=", value)
125
139
  end
126
140
 
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
141
  def self.register(extension)
142
142
  extension.registered(WebApplication)
143
143
  end
144
144
 
145
145
  private
146
146
 
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
147
  def build
177
- build_sessions
178
-
179
- middlewares = self.middlewares
180
148
  klass = self.class
149
+ m = middlewares
181
150
 
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) }
151
+ rules = []
152
+ rules = [[:all, {Rack::CACHE_CONTROL => "private, max-age=86400"}]] unless ENV["SIDEKIQ_WEB_TESTING"]
190
153
 
154
+ ::Rack::Builder.new do
155
+ use Rack::Static, urls: ["/stylesheets", "/images", "/javascripts"],
156
+ root: ASSETS,
157
+ cascade: true,
158
+ header_rules: rules
159
+ m.each { |middleware, block| use(*middleware, &block) }
160
+ use Sidekiq::Web::CsrfProtection unless $TESTING
191
161
  run WebApplication.new(klass)
192
162
  end
193
163
  end
@@ -196,18 +166,9 @@ module Sidekiq
196
166
  Sidekiq::WebApplication.helpers WebHelpers
197
167
  Sidekiq::WebApplication.helpers Sidekiq::Paginator
198
168
 
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)
169
+ Sidekiq::WebAction.class_eval <<-RUBY, __FILE__, __LINE__ + 1
170
+ def _render
171
+ #{ERB.new(File.read(Web::LAYOUT)).src}
211
172
  end
212
- end
173
+ RUBY
213
174
  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,235 +1,147 @@
1
1
  # frozen_string_literal: true
2
- require 'sidekiq/version'
3
- fail "Sidekiq #{Sidekiq::VERSION} does not support Ruby versions below 2.2.2." if RUBY_PLATFORM != 'java' && Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2.2')
4
2
 
5
- require 'sidekiq/logging'
6
- require 'sidekiq/client'
7
- require 'sidekiq/worker'
8
- require 'sidekiq/redis_connection'
9
- 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")
10
5
 
11
- require 'json'
6
+ begin
7
+ require "sidekiq-ent/version"
8
+ fail <<~EOM if Gem::Version.new(Sidekiq::Enterprise::VERSION).segments[0] != Sidekiq::MAJOR
12
9
 
13
- module Sidekiq
14
- NAME = 'Sidekiq'
15
- LICENSE = 'See LICENSE and the LGPL-3.0 for licensing details.'
16
-
17
- DEFAULTS = {
18
- queues: [],
19
- labels: [],
20
- concurrency: 10,
21
- require: '.',
22
- environment: nil,
23
- timeout: 8,
24
- poll_interval_average: nil,
25
- average_scheduled_poll_interval: 5,
26
- error_handlers: [],
27
- death_handlers: [],
28
- lifecycle_events: {
29
- startup: [],
30
- quiet: [],
31
- shutdown: [],
32
- heartbeat: [],
33
- },
34
- dead_max_jobs: 10_000,
35
- dead_timeout_in_seconds: 180 * 24 * 60 * 60, # 6 months
36
- reloader: proc { |&block| block.call },
37
- }
38
-
39
- DEFAULT_WORKER_OPTIONS = {
40
- 'retry' => true,
41
- 'queue' => 'default'
42
- }
43
-
44
- FAKE_INFO = {
45
- "redis_version" => "9.9.9",
46
- "uptime_in_days" => "9999",
47
- "connected_clients" => "9999",
48
- "used_memory_human" => "9P",
49
- "used_memory_peak_human" => "9P"
50
- }
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.
51
13
 
52
- def self.❨╯°□°❩╯︵┻━┻
53
- puts "Calm down, yo."
54
- end
14
+ EOM
15
+ rescue LoadError
16
+ end
55
17
 
56
- def self.options
57
- @options ||= DEFAULTS.dup
58
- end
59
- def self.options=(opts)
60
- @options = opts
61
- end
18
+ begin
19
+ require "sidekiq/pro/version"
20
+ fail <<~EOM if Gem::Version.new(Sidekiq::Pro::VERSION).segments[0] != Sidekiq::MAJOR
62
21
 
63
- ##
64
- # Configuration for Sidekiq server, use like:
65
- #
66
- # Sidekiq.configure_server do |config|
67
- # config.redis = { :namespace => 'myapp', :size => 25, :url => 'redis://myhost:8877/0' }
68
- # config.server_middleware do |chain|
69
- # chain.add MyServerHook
70
- # end
71
- # end
72
- def self.configure_server
73
- yield self if server?
74
- 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.
75
25
 
76
- ##
77
- # Configuration for Sidekiq client, use like:
78
- #
79
- # Sidekiq.configure_client do |config|
80
- # config.redis = { :namespace => 'myapp', :size => 1, :url => 'redis://myhost:8877/0' }
81
- # end
82
- def self.configure_client
83
- 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..."
84
46
  end
85
47
 
86
48
  def self.server?
87
49
  defined?(Sidekiq::CLI)
88
50
  end
89
51
 
90
- def self.redis
91
- raise ArgumentError, "requires a block" unless block_given?
92
- redis_pool.with do |conn|
93
- retryable = true
94
- begin
95
- yield conn
96
- rescue Redis::CommandError => ex
97
- #2550 Failover can cause the server to become a slave, need
98
- # to disconnect and reopen the socket to get back to the master.
99
- (conn.disconnect!; retryable = false; retry) if retryable && ex.message =~ /READONLY/
100
- raise
101
- end
102
- end
103
- end
104
-
105
- def self.redis_info
106
- redis do |conn|
107
- begin
108
- # admin commands can't go through redis-namespace starting
109
- # in redis-namespace 2.0
110
- if conn.respond_to?(:namespace)
111
- conn.redis.info
112
- else
113
- conn.info
114
- end
115
- rescue Redis::CommandError => ex
116
- #2850 return fake version when INFO command has (probably) been renamed
117
- raise unless ex.message =~ /unknown command/
118
- FAKE_INFO
119
- end
120
- end
52
+ def self.load_json(string)
53
+ JSON.parse(string)
121
54
  end
122
55
 
123
- def self.redis_pool
124
- @redis ||= Sidekiq::RedisConnection.create
56
+ def self.dump_json(object)
57
+ JSON.generate(object)
125
58
  end
126
59
 
127
- def self.redis=(hash)
128
- @redis = if hash.is_a?(ConnectionPool)
129
- hash
130
- else
131
- Sidekiq::RedisConnection.create(hash)
132
- end
60
+ def self.pro?
61
+ defined?(Sidekiq::Pro)
133
62
  end
134
63
 
135
- def self.client_middleware
136
- @client_chain ||= Middleware::Chain.new
137
- yield @client_chain if block_given?
138
- @client_chain
64
+ def self.ent?
65
+ defined?(Sidekiq::Enterprise)
139
66
  end
140
67
 
141
- def self.server_middleware
142
- @server_chain ||= default_server_middleware
143
- yield @server_chain if block_given?
144
- @server_chain
68
+ def self.redis_pool
69
+ (Thread.current[:sidekiq_capsule] || default_configuration).redis_pool
145
70
  end
146
71
 
147
- def self.default_server_middleware
148
- Middleware::Chain.new
72
+ def self.redis(&block)
73
+ (Thread.current[:sidekiq_capsule] || default_configuration).redis(&block)
149
74
  end
150
75
 
151
- def self.default_worker_options=(hash)
152
- # stringify
153
- @default_worker_options = default_worker_options.merge(Hash[hash.map{|k, v| [k.to_s, v]}])
154
- end
155
- def self.default_worker_options
156
- 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
157
78
  end
158
79
 
159
- def self.default_retries_exhausted=(prok)
160
- logger.info { "default_retries_exhausted is deprecated, please use `config.death_handlers << -> {|job, ex| }`" }
161
- return nil unless prok
162
- death_handlers << prok
80
+ def self.default_job_options=(hash)
81
+ @default_job_options = default_job_options.merge(hash.transform_keys(&:to_s))
163
82
  end
164
83
 
165
- ##
166
- # Death handlers are called when all retries for a job have been exhausted and
167
- # the job dies. It's the notification to your application
168
- # that this job will not succeed without manual intervention.
169
- #
170
- # Sidekiq.configure_server do |config|
171
- # config.death_handlers << ->(job, ex) do
172
- # end
173
- # end
174
- def self.death_handlers
175
- options[:death_handlers]
84
+ def self.default_job_options
85
+ @default_job_options ||= {"retry" => true, "queue" => "default"}
176
86
  end
177
87
 
178
- def self.load_json(string)
179
- JSON.parse(string)
180
- end
181
- def self.dump_json(object)
182
- JSON.generate(object)
88
+ def self.default_configuration
89
+ @config ||= Sidekiq::Config.new
183
90
  end
184
91
 
185
92
  def self.logger
186
- Sidekiq::Logging.logger
93
+ default_configuration.logger
187
94
  end
188
- def self.logger=(log)
189
- Sidekiq::Logging.logger = log
95
+
96
+ def self.configure_server(&block)
97
+ (@config_blocks ||= []) << block
98
+ yield default_configuration if server?
190
99
  end
191
100
 
192
- # How frequently Redis should be checked by a random Sidekiq process for
193
- # scheduled and retriable jobs. Each individual process will take turns by
194
- # waiting some multiple of this value.
195
- #
196
- # See sidekiq/scheduled.rb for an in-depth explanation of this value
197
- def self.average_scheduled_poll_interval=(interval)
198
- self.options[:average_scheduled_poll_interval] = interval
101
+ def self.freeze!
102
+ @frozen = true
103
+ @config_blocks = nil
199
104
  end
200
105
 
201
- # 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.
202
109
  #
203
- # Sidekiq.configure_server do |config|
204
- # 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]
205
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.
206
119
  #
207
- # The default error handler logs errors to Sidekiq.logger.
208
- def self.error_handlers
209
- 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)
210
132
  end
211
133
 
212
- # Register a block to run at a point in the Sidekiq lifecycle.
213
- # :startup, :quiet or :shutdown are valid events.
214
- #
215
- # Sidekiq.configure_server do |config|
216
- # config.on(:shutdown) do
217
- # puts "Goodbye cruel world!"
218
- # end
219
- # end
220
- def self.on(event, &block)
221
- raise ArgumentError, "Symbols only please: #{event}" unless event.is_a?(Symbol)
222
- raise ArgumentError, "Invalid event name: #{event}" unless options[:lifecycle_events].key?(event)
223
- options[:lifecycle_events][event] << block
134
+ def self.configure_client
135
+ yield default_configuration unless server?
224
136
  end
225
137
 
226
- # We are shutting down Sidekiq but what about workers that
138
+ # We are shutting down Sidekiq but what about threads that
227
139
  # are working on some long job? This error is
228
- # raised in workers that have not finished within the hard
140
+ # raised in jobs that have not finished within the hard
229
141
  # timeout limit. This is needed to rollback db transactions,
230
142
  # otherwise Ruby's Thread#kill will commit. See #377.
231
- # DO NOT RESCUE THIS ERROR IN YOUR WORKERS
143
+ # DO NOT RESCUE THIS ERROR IN YOUR JOBS
232
144
  class Shutdown < Interrupt; end
233
145
  end
234
146
 
235
- require 'sidekiq/rails' if defined?(::Rails::Engine)
147
+ require "sidekiq/rails" if defined?(::Rails::Engine)
data/sidekiq.gemspec CHANGED
@@ -1,23 +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.2'
22
- gem.add_dependency 'rack-protection', '>= 1.5.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"
23
30
  end