sidekiq 5.2.9 → 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.

Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -2
  3. data/.standard.yml +20 -0
  4. data/6.0-Upgrade.md +70 -0
  5. data/Changes.md +30 -8
  6. data/Ent-2.0-Upgrade.md +37 -0
  7. data/Ent-Changes.md +12 -0
  8. data/Gemfile +12 -11
  9. data/Gemfile.lock +196 -0
  10. data/Pro-5.0-Upgrade.md +25 -0
  11. data/Pro-Changes.md +12 -3
  12. data/README.md +16 -30
  13. data/Rakefile +5 -4
  14. data/bin/sidekiqload +26 -22
  15. data/bin/sidekiqmon +9 -0
  16. data/lib/generators/sidekiq/templates/worker_test.rb.erb +1 -1
  17. data/lib/generators/sidekiq/worker_generator.rb +12 -14
  18. data/lib/sidekiq/api.rb +138 -151
  19. data/lib/sidekiq/cli.rb +97 -162
  20. data/lib/sidekiq/client.rb +45 -46
  21. data/lib/sidekiq/delay.rb +5 -6
  22. data/lib/sidekiq/exception_handler.rb +10 -12
  23. data/lib/sidekiq/extensions/action_mailer.rb +10 -20
  24. data/lib/sidekiq/extensions/active_record.rb +9 -7
  25. data/lib/sidekiq/extensions/class_methods.rb +9 -7
  26. data/lib/sidekiq/extensions/generic_proxy.rb +4 -4
  27. data/lib/sidekiq/fetch.rb +5 -6
  28. data/lib/sidekiq/job_logger.rb +37 -7
  29. data/lib/sidekiq/job_retry.rb +45 -58
  30. data/lib/sidekiq/launcher.rb +59 -51
  31. data/lib/sidekiq/logger.rb +69 -0
  32. data/lib/sidekiq/manager.rb +7 -9
  33. data/lib/sidekiq/middleware/chain.rb +3 -2
  34. data/lib/sidekiq/middleware/i18n.rb +5 -7
  35. data/lib/sidekiq/monitor.rb +148 -0
  36. data/lib/sidekiq/paginator.rb +11 -12
  37. data/lib/sidekiq/processor.rb +52 -49
  38. data/lib/sidekiq/rails.rb +23 -29
  39. data/lib/sidekiq/redis_connection.rb +31 -37
  40. data/lib/sidekiq/scheduled.rb +17 -19
  41. data/lib/sidekiq/testing/inline.rb +2 -1
  42. data/lib/sidekiq/testing.rb +22 -23
  43. data/lib/sidekiq/util.rb +17 -14
  44. data/lib/sidekiq/version.rb +2 -1
  45. data/lib/sidekiq/web/action.rb +14 -10
  46. data/lib/sidekiq/web/application.rb +60 -57
  47. data/lib/sidekiq/web/helpers.rb +66 -67
  48. data/lib/sidekiq/web/router.rb +17 -14
  49. data/lib/sidekiq/web.rb +41 -49
  50. data/lib/sidekiq/worker.rb +124 -97
  51. data/lib/sidekiq.rb +53 -42
  52. data/sidekiq.gemspec +16 -16
  53. data/web/assets/javascripts/dashboard.js +2 -21
  54. data/web/locales/ja.yml +2 -1
  55. metadata +21 -31
  56. data/.travis.yml +0 -11
  57. data/bin/sidekiqctl +0 -20
  58. data/lib/sidekiq/core_ext.rb +0 -1
  59. data/lib/sidekiq/ctl.rb +0 -221
  60. data/lib/sidekiq/logging.rb +0 -122
  61. data/lib/sidekiq/middleware/server/active_record.rb +0 -23
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "logger"
4
+ require "time"
5
+
6
+ module Sidekiq
7
+ class Logger < ::Logger
8
+ def initialize(*args)
9
+ super
10
+
11
+ self.formatter = Sidekiq.log_formatter
12
+ end
13
+
14
+ def with_context(hash)
15
+ ctx.merge!(hash)
16
+ yield
17
+ ensure
18
+ hash.keys.each { |key| ctx.delete(key) }
19
+ end
20
+
21
+ def ctx
22
+ Thread.current[:sidekiq_context] ||= {}
23
+ end
24
+
25
+ module Formatters
26
+ class Base < ::Logger::Formatter
27
+ def tid
28
+ Thread.current["sidekiq_tid"] ||= (Thread.current.object_id ^ ::Process.pid).to_s(36)
29
+ end
30
+
31
+ def ctx
32
+ Thread.current[:sidekiq_context] ||= {}
33
+ end
34
+
35
+ def format_context
36
+ " " + ctx.compact.map { |k, v| "#{k}=#{v}" }.join(" ") if ctx.any?
37
+ end
38
+ end
39
+
40
+ class Pretty < Base
41
+ def call(severity, time, program_name, message)
42
+ "#{time.utc.iso8601(3)} pid=#{::Process.pid} tid=#{tid}#{format_context} #{severity}: #{message}\n"
43
+ end
44
+ end
45
+
46
+ class WithoutTimestamp < Pretty
47
+ def call(severity, time, program_name, message)
48
+ "pid=#{::Process.pid} tid=#{tid}#{format_context} #{severity}: #{message}\n"
49
+ end
50
+ end
51
+
52
+ class JSON < Base
53
+ def call(severity, time, program_name, message)
54
+ hash = {
55
+ ts: time.utc.iso8601(3),
56
+ pid: ::Process.pid,
57
+ tid: tid,
58
+ lvl: severity,
59
+ msg: message,
60
+ }
61
+ c = ctx
62
+ hash["ctx"] = c unless c.empty?
63
+
64
+ Sidekiq.dump_json(hash) << "\n"
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,12 +1,11 @@
1
1
  # frozen_string_literal: true
2
- require 'sidekiq/util'
3
- require 'sidekiq/processor'
4
- require 'sidekiq/fetch'
5
- require 'thread'
6
- require 'set'
7
2
 
8
- module Sidekiq
3
+ require "sidekiq/util"
4
+ require "sidekiq/processor"
5
+ require "sidekiq/fetch"
6
+ require "set"
9
7
 
8
+ module Sidekiq
10
9
  ##
11
10
  # The Manager is the central coordination point in Sidekiq, controlling
12
11
  # the lifecycle of the Processors.
@@ -27,7 +26,7 @@ module Sidekiq
27
26
  attr_reader :workers
28
27
  attr_reader :options
29
28
 
30
- def initialize(options={})
29
+ def initialize(options = {})
31
30
  logger.debug { options.inspect }
32
31
  @options = options
33
32
  @count = options[:concurrency] || 10
@@ -113,7 +112,7 @@ module Sidekiq
113
112
  end
114
113
 
115
114
  if cleanup.size > 0
116
- jobs = cleanup.map {|p| p.job }.compact
115
+ jobs = cleanup.map { |p| p.job }.compact
117
116
 
118
117
  logger.warn { "Terminating #{cleanup.size} busy worker threads" }
119
118
  logger.warn { "Work still in progress #{jobs.inspect}" }
@@ -132,6 +131,5 @@ module Sidekiq
132
131
  processor.kill
133
132
  end
134
133
  end
135
-
136
134
  end
137
135
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Sidekiq
3
4
  # Middleware is code configured to run before/after
4
5
  # a message is processed. It is patterned after Rack
@@ -106,7 +107,7 @@ module Sidekiq
106
107
  i = entries.index { |entry| entry.klass == newklass }
107
108
  new_entry = i.nil? ? Entry.new(newklass, *args) : entries.delete_at(i)
108
109
  i = entries.index { |entry| entry.klass == oldklass } || entries.count - 1
109
- entries.insert(i+1, new_entry)
110
+ entries.insert(i + 1, new_entry)
110
111
  end
111
112
 
112
113
  def exists?(klass)
@@ -139,7 +140,7 @@ module Sidekiq
139
140
 
140
141
  def initialize(klass, *args)
141
142
  @klass = klass
142
- @args = args
143
+ @args = args
143
144
  end
144
145
 
145
146
  def make_new
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  #
3
4
  # Simple middleware to save the current locale and restore it when the job executes.
4
5
  # Use it by requiring it in your initializer:
@@ -9,19 +10,16 @@ module Sidekiq::Middleware::I18n
9
10
  # Get the current locale and store it in the message
10
11
  # to be sent to Sidekiq.
11
12
  class Client
12
- def call(worker_class, msg, queue, redis_pool)
13
- msg['locale'] ||= I18n.locale
13
+ def call(_worker, msg, _queue, _redis)
14
+ msg["locale"] ||= I18n.locale
14
15
  yield
15
16
  end
16
17
  end
17
18
 
18
19
  # Pull the msg locale out and set the current thread to use it.
19
20
  class Server
20
- def call(worker, msg, queue)
21
- I18n.locale = msg['locale'] || I18n.default_locale
22
- yield
23
- ensure
24
- I18n.locale = I18n.default_locale
21
+ def call(_worker, msg, _queue, &block)
22
+ I18n.with_locale(msg.fetch("locale", I18n.default_locale), &block)
25
23
  end
26
24
  end
27
25
  end
@@ -0,0 +1,148 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "fileutils"
4
+ require "sidekiq/api"
5
+
6
+ class Sidekiq::Monitor
7
+ CMD = File.basename($PROGRAM_NAME)
8
+
9
+ attr_reader :stage
10
+
11
+ def self.print_usage
12
+ puts "#{CMD} - monitor Sidekiq from the command line."
13
+ puts
14
+ puts "Usage: #{CMD} status <section>"
15
+ puts
16
+ puts " <section> (optional) view a specific section of the status output"
17
+ puts " Valid sections are: #{Sidekiq::Monitor::Status::VALID_SECTIONS.join(", ")}"
18
+ puts
19
+ puts "Set REDIS_URL to the location of your Redis server if not monitoring localhost."
20
+ end
21
+
22
+ class Status
23
+ VALID_SECTIONS = %w[all version overview processes queues]
24
+ COL_PAD = 2
25
+
26
+ def display(section = nil)
27
+ section ||= "all"
28
+ unless VALID_SECTIONS.include? section
29
+ puts "I don't know how to check the status of '#{section}'!"
30
+ puts "Try one of these: #{VALID_SECTIONS.join(", ")}"
31
+ return
32
+ end
33
+ send(section)
34
+ rescue => e
35
+ puts "Couldn't get status: #{e}"
36
+ end
37
+
38
+ def all
39
+ version
40
+ puts
41
+ overview
42
+ puts
43
+ processes
44
+ puts
45
+ queues
46
+ end
47
+
48
+ def version
49
+ puts "Sidekiq #{Sidekiq::VERSION}"
50
+ puts Time.now
51
+ end
52
+
53
+ def overview
54
+ puts "---- Overview ----"
55
+ puts " Processed: #{delimit stats.processed}"
56
+ puts " Failed: #{delimit stats.failed}"
57
+ puts " Busy: #{delimit stats.workers_size}"
58
+ puts " Enqueued: #{delimit stats.enqueued}"
59
+ puts " Retries: #{delimit stats.retry_size}"
60
+ puts " Scheduled: #{delimit stats.scheduled_size}"
61
+ puts " Dead: #{delimit stats.dead_size}"
62
+ end
63
+
64
+ def processes
65
+ puts "---- Processes (#{process_set.size}) ----"
66
+ process_set.each_with_index do |process, index|
67
+ puts "#{process["identity"]} #{tags_for(process)}"
68
+ puts " Started: #{Time.at(process["started_at"])} (#{time_ago(process["started_at"])})"
69
+ puts " Threads: #{process["concurrency"]} (#{process["busy"]} busy)"
70
+ puts " Queues: #{split_multiline(process["queues"].sort, pad: 11)}"
71
+ puts "" unless (index + 1) == process_set.size
72
+ end
73
+ end
74
+
75
+ def queues
76
+ puts "---- Queues (#{queue_data.size}) ----"
77
+ columns = {
78
+ name: [:ljust, (["name"] + queue_data.map(&:name)).map(&:length).max + COL_PAD],
79
+ size: [:rjust, (["size"] + queue_data.map(&:size)).map(&:length).max + COL_PAD],
80
+ latency: [:rjust, (["latency"] + queue_data.map(&:latency)).map(&:length).max + COL_PAD],
81
+ }
82
+ columns.each { |col, (dir, width)| print col.to_s.upcase.public_send(dir, width) }
83
+ puts
84
+ queue_data.each do |q|
85
+ columns.each do |col, (dir, width)|
86
+ print q.send(col).public_send(dir, width)
87
+ end
88
+ puts
89
+ end
90
+ end
91
+
92
+ private
93
+
94
+ def delimit(number)
95
+ number.to_s.reverse.scan(/.{1,3}/).join(",").reverse
96
+ end
97
+
98
+ def split_multiline(values, opts = {})
99
+ return "none" unless values
100
+ pad = opts[:pad] || 0
101
+ max_length = opts[:max_length] || (80 - pad)
102
+ out = []
103
+ line = ""
104
+ values.each do |value|
105
+ if (line.length + value.length) > max_length
106
+ out << line
107
+ line = " " * pad
108
+ end
109
+ line << value + ", "
110
+ end
111
+ out << line[0..-3]
112
+ out.join("\n")
113
+ end
114
+
115
+ def tags_for(process)
116
+ tags = [
117
+ process["tag"],
118
+ process["labels"],
119
+ (process["quiet"] == "true" ? "quiet" : nil),
120
+ ].flatten.compact
121
+ tags.any? ? "[#{tags.join("] [")}]" : nil
122
+ end
123
+
124
+ def time_ago(timestamp)
125
+ seconds = Time.now - Time.at(timestamp)
126
+ return "just now" if seconds < 60
127
+ return "a minute ago" if seconds < 120
128
+ return "#{seconds.floor / 60} minutes ago" if seconds < 3600
129
+ return "an hour ago" if seconds < 7200
130
+ "#{seconds.floor / 60 / 60} hours ago"
131
+ end
132
+
133
+ QUEUE_STRUCT = Struct.new(:name, :size, :latency)
134
+ def queue_data
135
+ @queue_data ||= Sidekiq::Queue.all.map { |q|
136
+ QUEUE_STRUCT.new(q.name, q.size.to_s, sprintf("%#.2f", q.latency))
137
+ }
138
+ end
139
+
140
+ def process_set
141
+ @process_set ||= Sidekiq::ProcessSet.new
142
+ end
143
+
144
+ def stats
145
+ @stats ||= Sidekiq::Stats.new
146
+ end
147
+ end
148
+ end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Sidekiq
3
4
  module Paginator
4
-
5
- def page(key, pageidx=1, page_size=25, opts=nil)
5
+ def page(key, pageidx = 1, page_size = 25, opts = nil)
6
6
  current_page = pageidx.to_i < 1 ? 1 : pageidx.to_i
7
7
  pageidx = current_page - 1
8
8
  total_size = 0
@@ -14,30 +14,29 @@ module Sidekiq
14
14
  type = conn.type(key)
15
15
 
16
16
  case type
17
- when 'zset'
17
+ when "zset"
18
18
  rev = opts && opts[:reverse]
19
- total_size, items = conn.multi do
19
+ total_size, items = conn.multi {
20
20
  conn.zcard(key)
21
21
  if rev
22
- conn.zrevrange(key, starting, ending, :with_scores => true)
22
+ conn.zrevrange(key, starting, ending, with_scores: true)
23
23
  else
24
- conn.zrange(key, starting, ending, :with_scores => true)
24
+ conn.zrange(key, starting, ending, with_scores: true)
25
25
  end
26
- end
26
+ }
27
27
  [current_page, total_size, items]
28
- when 'list'
29
- total_size, items = conn.multi do
28
+ when "list"
29
+ total_size, items = conn.multi {
30
30
  conn.llen(key)
31
31
  conn.lrange(key, starting, ending)
32
- end
32
+ }
33
33
  [current_page, total_size, items]
34
- when 'none'
34
+ when "none"
35
35
  [1, 0, []]
36
36
  else
37
37
  raise "can't page a #{type}"
38
38
  end
39
39
  end
40
40
  end
41
-
42
41
  end
43
42
  end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
- require 'sidekiq/util'
3
- require 'sidekiq/fetch'
4
- require 'sidekiq/job_logger'
5
- require 'sidekiq/job_retry'
6
- require 'thread'
2
+
3
+ require "sidekiq/util"
4
+ require "sidekiq/fetch"
5
+ require "sidekiq/job_logger"
6
+ require "sidekiq/job_retry"
7
7
 
8
8
  module Sidekiq
9
9
  ##
@@ -23,7 +23,6 @@ module Sidekiq
23
23
  # to replace itself and exits.
24
24
  #
25
25
  class Processor
26
-
27
26
  include Util
28
27
 
29
28
  attr_reader :thread
@@ -37,19 +36,19 @@ module Sidekiq
37
36
  @thread = nil
38
37
  @strategy = (mgr.options[:fetch] || Sidekiq::BasicFetch).new(mgr.options)
39
38
  @reloader = Sidekiq.options[:reloader]
40
- @logging = (mgr.options[:job_logger] || Sidekiq::JobLogger).new
39
+ @job_logger = (mgr.options[:job_logger] || Sidekiq::JobLogger).new
41
40
  @retrier = Sidekiq::JobRetry.new
42
41
  end
43
42
 
44
- def terminate(wait=false)
43
+ def terminate(wait = false)
45
44
  @done = true
46
- return if !@thread
45
+ return unless @thread
47
46
  @thread.value if wait
48
47
  end
49
48
 
50
- def kill(wait=false)
49
+ def kill(wait = false)
51
50
  @done = true
52
- return if !@thread
51
+ return unless @thread
53
52
  # unlike the other actors, terminate does not wait
54
53
  # for the thread to finish because we don't know how
55
54
  # long the job will take to finish. Instead we
@@ -66,16 +65,12 @@ module Sidekiq
66
65
  private unless $TESTING
67
66
 
68
67
  def run
69
- begin
70
- while !@done
71
- process_one
72
- end
73
- @mgr.processor_stopped(self)
74
- rescue Sidekiq::Shutdown
75
- @mgr.processor_stopped(self)
76
- rescue Exception => ex
77
- @mgr.processor_died(self, ex)
78
- end
68
+ process_one until @done
69
+ @mgr.processor_stopped(self)
70
+ rescue Sidekiq::Shutdown
71
+ @mgr.processor_stopped(self)
72
+ rescue Exception => ex
73
+ @mgr.processor_died(self, ex)
79
74
  end
80
75
 
81
76
  def process_one
@@ -85,14 +80,15 @@ module Sidekiq
85
80
  end
86
81
 
87
82
  def get_one
88
- begin
89
- work = @strategy.retrieve_work
90
- (logger.info { "Redis is online, #{::Process.clock_gettime(::Process::CLOCK_MONOTONIC) - @down} sec downtime" }; @down = nil) if @down
91
- work
92
- rescue Sidekiq::Shutdown
93
- rescue => ex
94
- handle_fetch_exception(ex)
83
+ work = @strategy.retrieve_work
84
+ if @down
85
+ logger.info { "Redis is online, #{::Process.clock_gettime(::Process::CLOCK_MONOTONIC) - @down} sec downtime" }
86
+ @down = nil
95
87
  end
88
+ work
89
+ rescue Sidekiq::Shutdown
90
+ rescue => ex
91
+ handle_fetch_exception(ex)
96
92
  end
97
93
 
98
94
  def fetch
@@ -106,7 +102,7 @@ module Sidekiq
106
102
  end
107
103
 
108
104
  def handle_fetch_exception(ex)
109
- if !@down
105
+ unless @down
110
106
  @down = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
111
107
  logger.error("Error fetching job: #{ex}")
112
108
  handle_exception(ex)
@@ -121,18 +117,18 @@ module Sidekiq
121
117
  # job structure to the Web UI
122
118
  pristine = cloned(job_hash)
123
119
 
124
- Sidekiq::Logging.with_job_hash_context(job_hash) do
120
+ @job_logger.with_job_hash_context(job_hash) do
125
121
  @retrier.global(pristine, queue) do
126
- @logging.call(job_hash, queue) do
122
+ @job_logger.call(job_hash, queue) do
127
123
  stats(pristine, queue) do
128
124
  # Rails 5 requires a Reloader to wrap code execution. In order to
129
125
  # constantize the worker and instantiate an instance, we have to call
130
126
  # the Reloader. It handles code loading, db connection management, etc.
131
127
  # Effectively this block denotes a "unit of work" to Rails.
132
128
  @reloader.call do
133
- klass = constantize(job_hash['class'])
129
+ klass = constantize(job_hash["class"])
134
130
  worker = klass.new
135
- worker.jid = job_hash['jid']
131
+ worker.jid = job_hash["jid"]
136
132
  @retrier.local(worker, pristine, queue) do
137
133
  yield worker
138
134
  end
@@ -152,39 +148,44 @@ module Sidekiq
152
148
  begin
153
149
  job_hash = Sidekiq.load_json(jobstr)
154
150
  rescue => ex
155
- handle_exception(ex, { :context => "Invalid JSON for job", :jobstr => jobstr })
151
+ handle_exception(ex, {context: "Invalid JSON for job", jobstr: jobstr})
156
152
  # we can't notify because the job isn't a valid hash payload.
157
153
  DeadSet.new.kill(jobstr, notify_failure: false)
158
154
  return work.acknowledge
159
155
  end
160
156
 
161
- ack = true
157
+ ack = false
162
158
  begin
163
159
  dispatch(job_hash, queue) do |worker|
164
160
  Sidekiq.server_middleware.invoke(worker, job_hash, queue) do
165
- execute_job(worker, cloned(job_hash['args']))
161
+ execute_job(worker, cloned(job_hash["args"]))
166
162
  end
167
163
  end
164
+ ack = true
168
165
  rescue Sidekiq::Shutdown
169
166
  # Had to force kill this job because it didn't finish
170
167
  # within the timeout. Don't acknowledge the work since
171
168
  # we didn't properly finish it.
172
- ack = false
173
169
  rescue Sidekiq::JobRetry::Handled => h
174
170
  # this is the common case: job raised error and Sidekiq::JobRetry::Handled
175
171
  # signals that we created a retry successfully. We can acknowlege the job.
176
- e = h.cause ? h.cause : h
177
- handle_exception(e, { :context => "Job raised exception", :job => job_hash, :jobstr => jobstr })
172
+ ack = true
173
+ e = h.cause || h
174
+ handle_exception(e, {context: "Job raised exception", job: job_hash, jobstr: jobstr})
178
175
  raise e
179
176
  rescue Exception => ex
180
177
  # Unexpected error! This is very bad and indicates an exception that got past
181
178
  # the retry subsystem (e.g. network partition). We won't acknowledge the job
182
179
  # so it can be rescued when using Sidekiq Pro.
183
- ack = false
184
- handle_exception(ex, { :context => "Internal exception!", :job => job_hash, :jobstr => jobstr })
180
+ handle_exception(ex, {context: "Internal exception!", job: job_hash, jobstr: jobstr})
185
181
  raise e
186
182
  ensure
187
- work.acknowledge if ack
183
+ if ack
184
+ # We don't want a shutdown signal to interrupt job acknowledgment.
185
+ Thread.handle_interrupt(Sidekiq::Shutdown => :never) do
186
+ work.acknowledge
187
+ end
188
+ end
188
189
  end
189
190
  end
190
191
 
@@ -201,12 +202,16 @@ module Sidekiq
201
202
  @lock = Mutex.new
202
203
  end
203
204
 
204
- def incr(amount=1)
205
- @lock.synchronize { @value = @value + amount }
205
+ def incr(amount = 1)
206
+ @lock.synchronize { @value += amount }
206
207
  end
207
208
 
208
209
  def reset
209
- @lock.synchronize { val = @value; @value = 0; val }
210
+ @lock.synchronize {
211
+ val = @value
212
+ @value = 0
213
+ val
214
+ }
210
215
  end
211
216
  end
212
217
 
@@ -243,8 +248,7 @@ module Sidekiq
243
248
  WORKER_STATE = SharedWorkerState.new
244
249
 
245
250
  def stats(job_hash, queue)
246
- tid = Sidekiq::Logging.tid
247
- WORKER_STATE.set(tid, {:queue => queue, :payload => job_hash, :run_at => Time.now.to_i })
251
+ WORKER_STATE.set(tid, {queue: queue, payload: job_hash, run_at: Time.now.to_i})
248
252
 
249
253
  begin
250
254
  yield
@@ -265,7 +269,7 @@ module Sidekiq
265
269
  end
266
270
 
267
271
  def constantize(str)
268
- names = str.split('::')
272
+ names = str.split("::")
269
273
  names.shift if names.empty? || names.first.empty?
270
274
 
271
275
  names.inject(Object) do |constant, name|
@@ -274,6 +278,5 @@ module Sidekiq
274
278
  constant.const_defined?(name, false) ? constant.const_get(name, false) : constant.const_missing(name)
275
279
  end
276
280
  end
277
-
278
281
  end
279
282
  end
data/lib/sidekiq/rails.rb CHANGED
@@ -1,35 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "sidekiq/worker"
4
+
3
5
  module Sidekiq
4
6
  class Rails < ::Rails::Engine
5
- # We need to setup this up before any application configuration which might
6
- # change Sidekiq middleware.
7
+ # By including the Options module, we allow AJs to directly control sidekiq features
8
+ # via the *sidekiq_options* class method and, for instance, not use AJ's retry system.
9
+ # AJ retries don't show up in the Sidekiq UI Retries tab, save any error data, can't be
10
+ # manually retried, don't automatically die, etc.
7
11
  #
8
- # This hook happens after `Rails::Application` is inherited within
9
- # config/application.rb and before config is touched, usually within the
10
- # class block. Definitely before config/environments/*.rb and
11
- # config/initializers/*.rb.
12
- config.before_configuration do
13
- if ::Rails::VERSION::MAJOR < 5 && defined?(::ActiveRecord)
14
- Sidekiq.server_middleware do |chain|
15
- require 'sidekiq/middleware/server/active_record'
16
- chain.add Sidekiq::Middleware::Server::ActiveRecord
17
- end
12
+ # class SomeJob < ActiveJob::Base
13
+ # queue_as :default
14
+ # sidekiq_options retry: 3, backtrace: 10
15
+ # def perform
16
+ # end
17
+ # end
18
+ initializer "sidekiq.active_job_integration" do
19
+ ActiveSupport.on_load(:active_job) do
20
+ include ::Sidekiq::Worker::Options unless respond_to?(:sidekiq_options)
18
21
  end
19
22
  end
20
23
 
24
+ # This hook happens after all initializers are run, just before returning
25
+ # from config/environment.rb back to sidekiq/cli.rb.
26
+ # We have to add the reloader after initialize to see if cache_classes has
27
+ # been turned on.
28
+ #
29
+ # None of this matters on the client-side, only within the Sidekiq process itself.
21
30
  config.after_initialize do
22
- # This hook happens after all initializers are run, just before returning
23
- # from config/environment.rb back to sidekiq/cli.rb.
24
- # We have to add the reloader after initialize to see if cache_classes has
25
- # been turned on.
26
- #
27
- # None of this matters on the client-side, only within the Sidekiq process itself.
28
- #
29
31
  Sidekiq.configure_server do |_|
30
- if ::Rails::VERSION::MAJOR >= 5
31
- Sidekiq.options[:reloader] = Sidekiq::Rails::Reloader.new
32
- end
32
+ Sidekiq.options[:reloader] = Sidekiq::Rails::Reloader.new
33
33
  end
34
34
  end
35
35
 
@@ -48,11 +48,5 @@ module Sidekiq
48
48
  "#<Sidekiq::Rails::Reloader @app=#{@app.class.name}>"
49
49
  end
50
50
  end
51
- end if defined?(::Rails)
52
- end
53
-
54
- if defined?(::Rails) && ::Rails::VERSION::MAJOR < 4
55
- $stderr.puts("**************************************************")
56
- $stderr.puts("⛔️ WARNING: Sidekiq server is no longer supported by Rails 3.2 - please ensure your server/workers are updated")
57
- $stderr.puts("**************************************************")
51
+ end
58
52
  end