sidekiq 6.5.1 → 7.0.9

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 (108) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +142 -12
  3. data/README.md +40 -32
  4. data/bin/sidekiq +3 -8
  5. data/bin/sidekiqload +186 -118
  6. data/bin/sidekiqmon +3 -0
  7. data/lib/sidekiq/api.rb +226 -139
  8. data/lib/sidekiq/capsule.rb +127 -0
  9. data/lib/sidekiq/cli.rb +55 -61
  10. data/lib/sidekiq/client.rb +31 -18
  11. data/lib/sidekiq/component.rb +5 -1
  12. data/lib/sidekiq/config.rb +270 -0
  13. data/lib/sidekiq/deploy.rb +62 -0
  14. data/lib/sidekiq/embedded.rb +61 -0
  15. data/lib/sidekiq/fetch.rb +11 -14
  16. data/lib/sidekiq/job.rb +375 -10
  17. data/lib/sidekiq/job_logger.rb +2 -2
  18. data/lib/sidekiq/job_retry.rb +62 -41
  19. data/lib/sidekiq/job_util.rb +48 -14
  20. data/lib/sidekiq/launcher.rb +71 -65
  21. data/lib/sidekiq/logger.rb +1 -26
  22. data/lib/sidekiq/manager.rb +9 -11
  23. data/lib/sidekiq/metrics/query.rb +153 -0
  24. data/lib/sidekiq/metrics/shared.rb +95 -0
  25. data/lib/sidekiq/metrics/tracking.rb +136 -0
  26. data/lib/sidekiq/middleware/chain.rb +84 -48
  27. data/lib/sidekiq/middleware/current_attributes.rb +12 -17
  28. data/lib/sidekiq/monitor.rb +17 -4
  29. data/lib/sidekiq/paginator.rb +9 -1
  30. data/lib/sidekiq/processor.rb +27 -27
  31. data/lib/sidekiq/rails.rb +4 -9
  32. data/lib/sidekiq/redis_client_adapter.rb +8 -47
  33. data/lib/sidekiq/redis_connection.rb +11 -113
  34. data/lib/sidekiq/scheduled.rb +60 -33
  35. data/lib/sidekiq/testing.rb +5 -33
  36. data/lib/sidekiq/transaction_aware_client.rb +4 -5
  37. data/lib/sidekiq/version.rb +2 -1
  38. data/lib/sidekiq/web/action.rb +3 -3
  39. data/lib/sidekiq/web/application.rb +40 -9
  40. data/lib/sidekiq/web/csrf_protection.rb +1 -1
  41. data/lib/sidekiq/web/helpers.rb +32 -18
  42. data/lib/sidekiq/web.rb +7 -14
  43. data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
  44. data/lib/sidekiq.rb +76 -266
  45. data/sidekiq.gemspec +21 -10
  46. data/web/assets/javascripts/application.js +19 -1
  47. data/web/assets/javascripts/base-charts.js +106 -0
  48. data/web/assets/javascripts/chart.min.js +13 -0
  49. data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
  50. data/web/assets/javascripts/dashboard-charts.js +166 -0
  51. data/web/assets/javascripts/dashboard.js +3 -240
  52. data/web/assets/javascripts/metrics.js +264 -0
  53. data/web/assets/stylesheets/application-dark.css +4 -0
  54. data/web/assets/stylesheets/application-rtl.css +2 -91
  55. data/web/assets/stylesheets/application.css +65 -297
  56. data/web/locales/ar.yml +70 -70
  57. data/web/locales/cs.yml +62 -62
  58. data/web/locales/da.yml +60 -53
  59. data/web/locales/de.yml +65 -65
  60. data/web/locales/el.yml +43 -24
  61. data/web/locales/en.yml +82 -69
  62. data/web/locales/es.yml +68 -68
  63. data/web/locales/fa.yml +65 -65
  64. data/web/locales/fr.yml +67 -67
  65. data/web/locales/gd.yml +99 -0
  66. data/web/locales/he.yml +65 -64
  67. data/web/locales/hi.yml +59 -59
  68. data/web/locales/it.yml +53 -53
  69. data/web/locales/ja.yml +73 -68
  70. data/web/locales/ko.yml +52 -52
  71. data/web/locales/lt.yml +66 -66
  72. data/web/locales/nb.yml +61 -61
  73. data/web/locales/nl.yml +52 -52
  74. data/web/locales/pl.yml +45 -45
  75. data/web/locales/pt-br.yml +59 -69
  76. data/web/locales/pt.yml +51 -51
  77. data/web/locales/ru.yml +67 -66
  78. data/web/locales/sv.yml +53 -53
  79. data/web/locales/ta.yml +60 -60
  80. data/web/locales/uk.yml +62 -61
  81. data/web/locales/ur.yml +64 -64
  82. data/web/locales/vi.yml +67 -67
  83. data/web/locales/zh-cn.yml +43 -16
  84. data/web/locales/zh-tw.yml +42 -8
  85. data/web/views/_footer.erb +5 -2
  86. data/web/views/_job_info.erb +18 -2
  87. data/web/views/_metrics_period_select.erb +12 -0
  88. data/web/views/_nav.erb +1 -1
  89. data/web/views/_paging.erb +2 -0
  90. data/web/views/_poll_link.erb +1 -1
  91. data/web/views/busy.erb +43 -27
  92. data/web/views/dashboard.erb +36 -4
  93. data/web/views/metrics.erb +82 -0
  94. data/web/views/metrics_for_job.erb +68 -0
  95. data/web/views/morgue.erb +5 -9
  96. data/web/views/queue.erb +15 -15
  97. data/web/views/queues.erb +3 -1
  98. data/web/views/retries.erb +5 -9
  99. data/web/views/scheduled.erb +12 -13
  100. metadata +60 -27
  101. data/lib/sidekiq/.DS_Store +0 -0
  102. data/lib/sidekiq/delay.rb +0 -43
  103. data/lib/sidekiq/extensions/action_mailer.rb +0 -48
  104. data/lib/sidekiq/extensions/active_record.rb +0 -43
  105. data/lib/sidekiq/extensions/class_methods.rb +0 -43
  106. data/lib/sidekiq/extensions/generic_proxy.rb +0 -33
  107. data/lib/sidekiq/worker.rb +0 -367
  108. /data/{LICENSE → LICENSE.txt} +0 -0
@@ -0,0 +1,127 @@
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
+ attr_reader :mode
25
+ attr_reader :weights
26
+
27
+ def initialize(name, config)
28
+ @name = name
29
+ @config = config
30
+ @queues = ["default"]
31
+ @weights = {"default" => 0}
32
+ @concurrency = config[:concurrency]
33
+ @mode = :strict
34
+ end
35
+
36
+ def fetcher
37
+ @fetcher ||= begin
38
+ inst = (config[:fetch_class] || Sidekiq::BasicFetch).new(self)
39
+ inst.setup(config[:fetch_setup]) if inst.respond_to?(:setup)
40
+ inst
41
+ end
42
+ end
43
+
44
+ def stop
45
+ fetcher&.bulk_requeue([])
46
+ end
47
+
48
+ # Sidekiq checks queues in three modes:
49
+ # - :strict - all queues have 0 weight and are checked strictly in order
50
+ # - :weighted - queues have arbitrary weight between 1 and N
51
+ # - :random - all queues have weight of 1
52
+ def queues=(val)
53
+ @weights = {}
54
+ @queues = Array(val).each_with_object([]) do |qstr, memo|
55
+ arr = qstr
56
+ arr = qstr.split(",") if qstr.is_a?(String)
57
+ name, weight = arr
58
+ @weights[name] = weight.to_i
59
+ [weight.to_i, 1].max.times do
60
+ memo << name
61
+ end
62
+ end
63
+ @mode = if @weights.values.all?(&:zero?)
64
+ :strict
65
+ elsif @weights.values.all? { |x| x == 1 }
66
+ :random
67
+ else
68
+ :weighted
69
+ end
70
+ end
71
+
72
+ # Allow the middleware to be different per-capsule.
73
+ # Avoid if possible and add middleware globally so all
74
+ # capsules share the same chains. Easier to debug that way.
75
+ def client_middleware
76
+ @client_chain ||= config.client_middleware.copy_for(self)
77
+ yield @client_chain if block_given?
78
+ @client_chain
79
+ end
80
+
81
+ def server_middleware
82
+ @server_chain ||= config.server_middleware.copy_for(self)
83
+ yield @server_chain if block_given?
84
+ @server_chain
85
+ end
86
+
87
+ def redis_pool
88
+ Thread.current[:sidekiq_redis_pool] || local_redis_pool
89
+ end
90
+
91
+ def local_redis_pool
92
+ # connection pool is lazy, it will not create connections unless you actually need them
93
+ # so don't be skimpy!
94
+ @redis ||= config.new_redis_pool(@concurrency, name)
95
+ end
96
+
97
+ def redis
98
+ raise ArgumentError, "requires a block" unless block_given?
99
+ redis_pool.with do |conn|
100
+ retryable = true
101
+ begin
102
+ yield conn
103
+ rescue RedisClientAdapter::BaseError => ex
104
+ # 2550 Failover can cause the server to become a replica, need
105
+ # to disconnect and reopen the socket to get back to the primary.
106
+ # 4495 Use the same logic if we have a "Not enough replicas" error from the primary
107
+ # 4985 Use the same logic when a blocking command is force-unblocked
108
+ # The same retry logic is also used in client.rb
109
+ if retryable && ex.message =~ /READONLY|NOREPLICAS|UNBLOCKED/
110
+ conn.close
111
+ retryable = false
112
+ retry
113
+ end
114
+ raise
115
+ end
116
+ end
117
+ end
118
+
119
+ def lookup(name)
120
+ config.lookup(name)
121
+ end
122
+
123
+ def logger
124
+ config.logger
125
+ end
126
+ end
127
+ end
data/lib/sidekiq/cli.rb CHANGED
@@ -9,7 +9,9 @@ require "erb"
9
9
  require "fileutils"
10
10
 
11
11
  require "sidekiq"
12
+ require "sidekiq/config"
12
13
  require "sidekiq/component"
14
+ require "sidekiq/capsule"
13
15
  require "sidekiq/launcher"
14
16
 
15
17
  module Sidekiq # :nodoc:
@@ -22,9 +24,7 @@ module Sidekiq # :nodoc:
22
24
  attr_accessor :config
23
25
 
24
26
  def parse(args = ARGV.dup)
25
- @config = Sidekiq
26
- @config[:error_handlers].clear
27
- @config[:error_handlers] << @config.method(:default_error_handler)
27
+ @config ||= Sidekiq.default_configuration
28
28
 
29
29
  setup_options(args)
30
30
  initialize_logger
@@ -41,7 +41,7 @@ module Sidekiq # :nodoc:
41
41
  def run(boot_app: true)
42
42
  boot_application if boot_app
43
43
 
44
- if environment == "development" && $stdout.tty? && @config.log_formatter.is_a?(Sidekiq::Logger::Formatters::Pretty)
44
+ if environment == "development" && $stdout.tty? && @config.logger.formatter.is_a?(Sidekiq::Logger::Formatters::Pretty)
45
45
  print_banner
46
46
  end
47
47
  logger.info "Booted Rails #{::Rails.version} application in #{environment} environment" if rails_app?
@@ -73,26 +73,27 @@ module Sidekiq # :nodoc:
73
73
  # touch the connection pool so it is created before we
74
74
  # fire startup and start multithreading.
75
75
  info = @config.redis_info
76
- ver = info["redis_version"]
77
- raise "You are connecting to Redis v#{ver}, Sidekiq requires Redis v4.0.0 or greater" if ver < "4"
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
78
 
79
79
  maxmemory_policy = info["maxmemory_policy"]
80
- if maxmemory_policy != "noeviction"
80
+ if maxmemory_policy != "noeviction" && maxmemory_policy != ""
81
+ # Redis Enterprise Cloud returns "" for their policy 😳
81
82
  logger.warn <<~EOM
82
83
 
83
84
 
84
85
  WARNING: Your Redis instance will evict Sidekiq data under heavy load.
85
86
  The 'noeviction' maxmemory policy is recommended (current policy: '#{maxmemory_policy}').
86
- See: https://github.com/mperham/sidekiq/wiki/Using-Redis#memory
87
+ See: https://github.com/sidekiq/sidekiq/wiki/Using-Redis#memory
87
88
 
88
89
  EOM
89
90
  end
90
91
 
91
92
  # Since the user can pass us a connection pool explicitly in the initializer, we
92
93
  # need to verify the size is large enough or else Sidekiq's performance is dramatically slowed.
93
- cursize = @config.redis_pool.size
94
- needed = @config[:concurrency] + 2
95
- raise "Your pool of #{cursize} Redis connections is too small, please increase the size to at least #{needed}" if cursize < needed
94
+ @config.capsules.each_pair do |name, cap|
95
+ raise ArgumentError, "Pool size too small for #{name}" if cap.redis_pool.size < cap.concurrency
96
+ end
96
97
 
97
98
  # cache process identity
98
99
  @config[:identity] = identity
@@ -104,8 +105,8 @@ module Sidekiq # :nodoc:
104
105
  # Starting here the process will now have multiple threads running.
105
106
  fire_event(:startup, reverse: false, reraise: true)
106
107
 
107
- logger.debug { "Client Middleware: #{@config.client_middleware.map(&:klass).join(", ")}" }
108
- logger.debug { "Server Middleware: #{@config.server_middleware.map(&:klass).join(", ")}" }
108
+ logger.debug { "Client Middleware: #{@config.default_capsule.client_middleware.map(&:klass).join(", ")}" }
109
+ logger.debug { "Server Middleware: #{@config.default_capsule.server_middleware.map(&:klass).join(", ")}" }
109
110
 
110
111
  launch(self_read)
111
112
  end
@@ -138,19 +139,34 @@ module Sidekiq # :nodoc:
138
139
  end
139
140
  end
140
141
 
141
- def self.w
142
- "\e[37m"
142
+ HOLIDAY_COLORS = {
143
+ # got other color-specific holidays from around the world?
144
+ # https://developer-book.com/post/definitive-guide-for-colored-text-in-terminal/#256-color-escape-codes
145
+ "3-17" => "\e[1;32m", # St. Patrick's Day green
146
+ "10-31" => "\e[38;5;208m" # Halloween orange
147
+ }
148
+
149
+ def self.day
150
+ @@day ||= begin
151
+ t = Date.today
152
+ "#{t.month}-#{t.day}"
153
+ end
143
154
  end
144
155
 
145
156
  def self.r
146
- "\e[31m"
157
+ @@r ||= HOLIDAY_COLORS[day] || "\e[1;31m"
147
158
  end
148
159
 
149
160
  def self.b
150
- "\e[30m"
161
+ @@b ||= HOLIDAY_COLORS[day] || "\e[30m"
162
+ end
163
+
164
+ def self.w
165
+ "\e[1;37m"
151
166
  end
152
167
 
153
168
  def self.reset
169
+ @@b = @@r = @@day = nil
154
170
  "\e[0m"
155
171
  end
156
172
 
@@ -163,7 +179,7 @@ module Sidekiq # :nodoc:
163
179
  #{w} ,$$$$$b#{b}/#{w}md$$$P^'
164
180
  #{w} .d$$$$$$#{b}/#{w}$$$P'
165
181
  #{w} $$^' `"#{b}/#{w}$$$' #{r}____ _ _ _ _
166
- #{w} $: ,$$: #{r} / ___|(_) __| | ___| | _(_) __ _
182
+ #{w} $: #{b}'#{w},$$: #{r} / ___|(_) __| | ___| | _(_) __ _
167
183
  #{w} `b :$$ #{r} \\___ \\| |/ _` |/ _ \\ |/ / |/ _` |
168
184
  #{w} $$: #{r} ___) | | (_| | __/ <| | (_| |
169
185
  #{w} $$ #{r}|____/|_|\\__,_|\\___|_|\\_\\_|\\__, |
@@ -260,6 +276,18 @@ module Sidekiq # :nodoc:
260
276
 
261
277
  # merge with defaults
262
278
  @config.merge!(opts)
279
+
280
+ @config.default_capsule.tap do |cap|
281
+ cap.queues = opts[:queues]
282
+ cap.concurrency = opts[:concurrency] || @config[:concurrency]
283
+ end
284
+
285
+ opts[:capsules]&.each do |name, cap_config|
286
+ @config.capsule(name.to_s) do |cap|
287
+ cap.queues = cap_config[:queues]
288
+ cap.concurrency = cap_config[:concurrency]
289
+ end
290
+ end
263
291
  end
264
292
 
265
293
  def boot_application
@@ -267,12 +295,11 @@ module Sidekiq # :nodoc:
267
295
 
268
296
  if File.directory?(@config[:require])
269
297
  require "rails"
270
- if ::Rails::VERSION::MAJOR < 5
271
- raise "Sidekiq no longer supports this version of Rails"
272
- else
273
- require "sidekiq/rails"
274
- require File.expand_path("#{@config[:require]}/config/environment.rb")
298
+ if ::Rails::VERSION::MAJOR < 6
299
+ warn "Sidekiq #{Sidekiq::VERSION} only supports Rails 6+"
275
300
  end
301
+ require "sidekiq/rails"
302
+ require File.expand_path("#{@config[:require]}/config/environment.rb")
276
303
  @config[:tag] ||= default_tag
277
304
  else
278
305
  require @config[:require]
@@ -320,10 +347,6 @@ module Sidekiq # :nodoc:
320
347
  opts[:concurrency] = Integer(arg)
321
348
  end
322
349
 
323
- o.on "-d", "--daemon", "Daemonize process" do |arg|
324
- puts "ERROR: Daemonization mode was removed in Sidekiq 6.0, please use a proper process supervisor to start and manage your services"
325
- end
326
-
327
350
  o.on "-e", "--environment ENV", "Application environment" do |arg|
328
351
  opts[:environment] = arg
329
352
  end
@@ -333,8 +356,8 @@ module Sidekiq # :nodoc:
333
356
  end
334
357
 
335
358
  o.on "-q", "--queue QUEUE[,WEIGHT]", "Queues to process with optional weights" do |arg|
336
- queue, weight = arg.split(",")
337
- parse_queue opts, queue, weight
359
+ opts[:queues] ||= []
360
+ opts[:queues] << arg
338
361
  end
339
362
 
340
363
  o.on "-r", "--require [PATH|DIR]", "Location of Rails application with jobs or file to require" do |arg|
@@ -353,15 +376,7 @@ module Sidekiq # :nodoc:
353
376
  opts[:config_file] = arg
354
377
  end
355
378
 
356
- o.on "-L", "--logfile PATH", "path to writable logfile" do |arg|
357
- puts "ERROR: Logfile redirection was removed in Sidekiq 6.0, Sidekiq will only log to STDOUT"
358
- end
359
-
360
- o.on "-P", "--pidfile PATH", "path to pidfile" do |arg|
361
- puts "ERROR: PID file creation was removed in Sidekiq 6.0, please use a proper process supervisor to start and manage your services"
362
- end
363
-
364
- o.on "-V", "--version", "Print version and exit" do |arg|
379
+ o.on "-V", "--version", "Print version and exit" do
365
380
  puts "Sidekiq #{Sidekiq::VERSION}"
366
381
  die(0)
367
382
  end
@@ -383,7 +398,7 @@ module Sidekiq # :nodoc:
383
398
  def parse_config(path)
384
399
  erb = ERB.new(File.read(path))
385
400
  erb.filename = File.expand_path(path)
386
- opts = load_yaml(erb.result) || {}
401
+ opts = YAML.safe_load(erb.result, permitted_classes: [Symbol], aliases: true) || {}
387
402
 
388
403
  if opts.respond_to? :deep_symbolize_keys!
389
404
  opts.deep_symbolize_keys!
@@ -394,31 +409,9 @@ module Sidekiq # :nodoc:
394
409
  opts = opts.merge(opts.delete(environment.to_sym) || {})
395
410
  opts.delete(:strict)
396
411
 
397
- parse_queues(opts, opts.delete(:queues) || [])
398
-
399
412
  opts
400
413
  end
401
414
 
402
- def load_yaml(src)
403
- if Psych::VERSION > "4.0"
404
- YAML.safe_load(src, permitted_classes: [Symbol], aliases: true)
405
- else
406
- YAML.load(src)
407
- end
408
- end
409
-
410
- def parse_queues(opts, queues_and_weights)
411
- queues_and_weights.each { |queue_and_weight| parse_queue(opts, *queue_and_weight) }
412
- end
413
-
414
- def parse_queue(opts, queue, weight = nil)
415
- opts[:queues] ||= []
416
- opts[:strict] = true if opts[:strict].nil?
417
- raise ArgumentError, "queues: #{queue} cannot be defined twice" if opts[:queues].include?(queue)
418
- [weight.to_i, 1].max.times { opts[:queues] << queue.to_s }
419
- opts[:strict] = false if weight.to_i > 0
420
- end
421
-
422
415
  def rails_app?
423
416
  defined?(::Rails) && ::Rails.respond_to?(:application)
424
417
  end
@@ -426,3 +419,4 @@ module Sidekiq # :nodoc:
426
419
  end
427
420
 
428
421
  require "sidekiq/systemd"
422
+ require "sidekiq/metrics/tracking"
@@ -21,7 +21,6 @@ module Sidekiq
21
21
  # Sidekiq.client_middleware but you can change as necessary.
22
22
  #
23
23
  def middleware(&block)
24
- @chain ||= Sidekiq.client_middleware
25
24
  if block
26
25
  @chain = @chain.dup
27
26
  yield @chain
@@ -31,18 +30,32 @@ module Sidekiq
31
30
 
32
31
  attr_accessor :redis_pool
33
32
 
34
- # Sidekiq::Client normally uses the default Redis pool but you may
35
- # pass a custom ConnectionPool if you want to shard your
36
- # Sidekiq jobs across several Redis instances (for scalability
37
- # reasons, e.g.)
33
+ # Sidekiq::Client is responsible for pushing job payloads to Redis.
34
+ # Requires the :pool or :config keyword argument.
38
35
  #
39
- # Sidekiq::Client.new(ConnectionPool.new { Redis.new })
36
+ # Sidekiq::Client.new(pool: Sidekiq::RedisConnection.create)
40
37
  #
41
- # Generally this is only needed for very large Sidekiq installs processing
42
- # thousands of jobs per second. I don't recommend sharding unless you
43
- # cannot scale any other way (e.g. splitting your app into smaller apps).
44
- def initialize(redis_pool = nil)
45
- @redis_pool = redis_pool || Thread.current[:sidekiq_via_pool] || Sidekiq.redis_pool
38
+ # Inside the Sidekiq process, you can reuse the configured resources:
39
+ #
40
+ # Sidekiq::Client.new(config: config)
41
+ #
42
+ # @param pool [ConnectionPool] explicit Redis pool to use
43
+ # @param config [Sidekiq::Config] use the pool and middleware from the given Sidekiq container
44
+ # @param chain [Sidekiq::Middleware::Chain] use the given middleware chain
45
+ def initialize(*args, **kwargs)
46
+ if args.size == 1 && kwargs.size == 0
47
+ warn "Sidekiq::Client.new(pool) is deprecated, please use Sidekiq::Client.new(pool: pool), #{caller(0..3)}"
48
+ # old calling method, accept 1 pool argument
49
+ @redis_pool = args[0]
50
+ @chain = Sidekiq.default_configuration.client_middleware
51
+ @config = Sidekiq.default_configuration
52
+ else
53
+ # new calling method: keyword arguments
54
+ @config = kwargs[:config] || Sidekiq.default_configuration
55
+ @redis_pool = kwargs[:pool] || Thread.current[:sidekiq_redis_pool] || @config&.redis_pool
56
+ @chain = kwargs[:chain] || @config&.client_middleware
57
+ raise ArgumentError, "No Redis pool available for Sidekiq::Client" unless @redis_pool
58
+ end
46
59
  end
47
60
 
48
61
  ##
@@ -135,11 +148,11 @@ module Sidekiq
135
148
  # you cannot scale any other way (e.g. splitting your app into smaller apps).
136
149
  def self.via(pool)
137
150
  raise ArgumentError, "No pool given" if pool.nil?
138
- current_sidekiq_pool = Thread.current[:sidekiq_via_pool]
139
- Thread.current[:sidekiq_via_pool] = pool
151
+ current_sidekiq_pool = Thread.current[:sidekiq_redis_pool]
152
+ Thread.current[:sidekiq_redis_pool] = pool
140
153
  yield
141
154
  ensure
142
- Thread.current[:sidekiq_via_pool] = current_sidekiq_pool
155
+ Thread.current[:sidekiq_redis_pool] = current_sidekiq_pool
143
156
  end
144
157
 
145
158
  class << self
@@ -176,7 +189,7 @@ module Sidekiq
176
189
  def enqueue_to_in(queue, interval, klass, *args)
177
190
  int = interval.to_f
178
191
  now = Time.now.to_f
179
- ts = (int < 1_000_000_000 ? now + int : int)
192
+ ts = ((int < 1_000_000_000) ? now + int : int)
180
193
 
181
194
  item = {"class" => klass, "args" => args, "at" => ts, "queue" => queue}
182
195
  item.delete("at") if ts <= now
@@ -201,14 +214,14 @@ module Sidekiq
201
214
  conn.pipelined do |pipeline|
202
215
  atomic_push(pipeline, payloads)
203
216
  end
204
- rescue RedisConnection.adapter::BaseError => ex
217
+ rescue RedisClient::Error => ex
205
218
  # 2550 Failover can cause the server to become a replica, need
206
219
  # to disconnect and reopen the socket to get back to the primary.
207
220
  # 4495 Use the same logic if we have a "Not enough replicas" error from the primary
208
221
  # 4985 Use the same logic when a blocking command is force-unblocked
209
222
  # The retry logic is copied from sidekiq.rb
210
223
  if retryable && ex.message =~ /READONLY|NOREPLICAS|UNBLOCKED/
211
- conn.disconnect!
224
+ conn.close
212
225
  retryable = false
213
226
  retry
214
227
  end
@@ -231,7 +244,7 @@ module Sidekiq
231
244
  entry["enqueued_at"] = now
232
245
  Sidekiq.dump_json(entry)
233
246
  }
234
- conn.sadd("queues", queue)
247
+ conn.sadd("queues", [queue])
235
248
  conn.lpush("queue:#{queue}", to_push)
236
249
  end
237
250
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Sidekiq
2
4
  ##
3
5
  # Sidekiq::Component assumes a config instance is available at @config
@@ -47,8 +49,10 @@ module Sidekiq
47
49
  end
48
50
 
49
51
  def fire_event(event, options = {})
52
+ oneshot = options.fetch(:oneshot, true)
50
53
  reverse = options[:reverse]
51
54
  reraise = options[:reraise]
55
+ logger.debug("Firing #{event} event") if oneshot
52
56
 
53
57
  arr = config[:lifecycle_events][event]
54
58
  arr.reverse! if reverse
@@ -58,7 +62,7 @@ module Sidekiq
58
62
  handle_exception(ex, {context: "Exception during Sidekiq lifecycle event.", event: event})
59
63
  raise ex if reraise
60
64
  end
61
- arr.clear # once we've fired an event, we never fire it again
65
+ arr.clear if oneshot # once we've fired an event, we never fire it again
62
66
  end
63
67
  end
64
68
  end