sidekiq 6.5.7 → 6.5.12

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a46b127af053d0d8e34960975ba328973778e74e5e11c972b7ed90ad3ff37e81
4
- data.tar.gz: b879598b3c9219e52b2c61ecc33fc03670a779a9afc3c5651f99240021391551
3
+ metadata.gz: 55c6f9a8c0f2810bcbe7744c95204893d73f534666f6091c74dcb5199e7a4a28
4
+ data.tar.gz: c42690ef0d1876c94eb51fb68319275d11f10169826180db921b34d6334a1a54
5
5
  SHA512:
6
- metadata.gz: b30b0d0ddf63bf32cf9dadce9090112fcc0a26f3aa255fa49b784197a22ccc49280c323a7cbcccbd64fc7fb78b0273824c763bf7fc06dfcc0f310562099597de
7
- data.tar.gz: e987d3347e7bd83a7abda98c72b1f9c79f7a75686e1895a4ad6e937c8eb3350a90fc03f010ea7c781b5a3609e5e255c2773cffda3e4c4570470ef8f1ed108316
6
+ metadata.gz: 461b559e18cbdf8fe6ba20ab9fa38d08fd3b7b8d14dce7a7f9369d678e92bd25c07734bc14b0167f83589c0f03501897195b3fdf9cfd5de5a60f039bf7436f98
7
+ data.tar.gz: ce0490b438a22a71c37e5a65193a7728e3297b437730d30a3653807ff1e89476db1f8c62d8de50c0c8cebbbce2ba6fb65f110855e071c62746fe8697a0f636e1
data/Changes.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  [Sidekiq Changes](https://github.com/mperham/sidekiq/blob/main/Changes.md) | [Sidekiq Pro Changes](https://github.com/mperham/sidekiq/blob/main/Pro-Changes.md) | [Sidekiq Enterprise Changes](https://github.com/mperham/sidekiq/blob/main/Ent-Changes.md)
4
4
 
5
+ 6.5.11
6
+ ----------
7
+
8
+ - Fix for Rails 7.1 [#6067]
9
+
10
+ 6.5.10
11
+ ----------
12
+
13
+ - Web UI DoS vector [#6045] CVE-2023-26141
14
+ - Fix broadcast logger with Rails 7.1 [#6054]
15
+
16
+ 6.5.9
17
+ ----------
18
+
19
+ - Ensure Sidekiq.options[:environment] == RAILS_ENV [#5932]
20
+
21
+ 6.5.8
22
+ ----------
23
+
24
+ - Fail if using a bad version of scout_apm [#5616]
25
+ - Add pagination to Busy page [#5556]
26
+ - Speed up WorkSet#each [#5559]
27
+ - Adjust CurrentAttributes to work with the String class name so we aren't referencing
28
+ the Class within a Rails initializer [#5536]
29
+
5
30
  6.5.7
6
31
  ----------
7
32
 
data/lib/sidekiq/api.rb CHANGED
@@ -1103,24 +1103,31 @@ module Sidekiq
1103
1103
 
1104
1104
  def each(&block)
1105
1105
  results = []
1106
+ procs = nil
1107
+ all_works = nil
1108
+
1106
1109
  Sidekiq.redis do |conn|
1107
- procs = conn.sscan_each("processes").to_a
1108
- procs.sort.each do |key|
1109
- valid, workers = conn.pipelined { |pipeline|
1110
- pipeline.exists?(key)
1110
+ procs = conn.sscan_each("processes").to_a.sort
1111
+
1112
+ all_works = conn.pipelined do |pipeline|
1113
+ procs.each do |key|
1111
1114
  pipeline.hgetall("#{key}:work")
1112
- }
1113
- next unless valid
1114
- workers.each_pair do |tid, json|
1115
- hsh = Sidekiq.load_json(json)
1116
- p = hsh["payload"]
1117
- # avoid breaking API, this is a side effect of the JSON optimization in #4316
1118
- hsh["payload"] = Sidekiq.load_json(p) if p.is_a?(String)
1119
- results << [key, tid, hsh]
1120
1115
  end
1121
1116
  end
1122
1117
  end
1123
1118
 
1119
+ procs.zip(all_works).each do |key, workers|
1120
+ workers.each_pair do |tid, json|
1121
+ next if json.empty?
1122
+
1123
+ hsh = Sidekiq.load_json(json)
1124
+ p = hsh["payload"]
1125
+ # avoid breaking API, this is a side effect of the JSON optimization in #4316
1126
+ hsh["payload"] = Sidekiq.load_json(p) if p.is_a?(String)
1127
+ results << [key, tid, hsh]
1128
+ end
1129
+ end
1130
+
1124
1131
  results.sort_by { |(_, _, hsh)| hsh["run_at"] }.each(&block)
1125
1132
  end
1126
1133
 
data/lib/sidekiq/cli.rb CHANGED
@@ -12,6 +12,17 @@ require "sidekiq"
12
12
  require "sidekiq/component"
13
13
  require "sidekiq/launcher"
14
14
 
15
+ # module ScoutApm
16
+ # VERSION = "5.3.1"
17
+ # end
18
+ fail <<~EOM if defined?(ScoutApm::VERSION) && ScoutApm::VERSION < "5.2.0"
19
+
20
+
21
+ scout_apm v#{ScoutApm::VERSION} is unsafe with Sidekiq 6.5. Please run `bundle up scout_apm` to upgrade to 5.2.0 or greater.
22
+
23
+
24
+ EOM
25
+
15
26
  module Sidekiq # :nodoc:
16
27
  class CLI
17
28
  include Sidekiq::Component
@@ -214,6 +225,7 @@ module Sidekiq # :nodoc:
214
225
  # Both Sinatra 2.0+ and Sidekiq support this term.
215
226
  # RAILS_ENV and RACK_ENV are there for legacy support.
216
227
  @environment = cli_env || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
228
+ config[:environment] = @environment
217
229
  end
218
230
 
219
231
  def symbolize_keys_deep!(hash)
@@ -176,7 +176,7 @@ module Sidekiq
176
176
  def enqueue_to_in(queue, interval, klass, *args)
177
177
  int = interval.to_f
178
178
  now = Time.now.to_f
179
- ts = (int < 1_000_000_000 ? now + int : int)
179
+ ts = ((int < 1_000_000_000) ? now + int : int)
180
180
 
181
181
  item = {"class" => klass, "args" => args, "at" => ts, "queue" => queue}
182
182
  item.delete("at") if ts <= now
@@ -123,7 +123,7 @@ module Sidekiq
123
123
  def series_avg(metric = "ms")
124
124
  series[metric].each_with_object(Hash.new(0)) do |(bucket, value), result|
125
125
  completed = series.dig("p", bucket) - series.dig("f", bucket)
126
- result[bucket] = completed == 0 ? 0 : value.to_f / completed
126
+ result[bucket] = (completed == 0) ? 0 : value.to_f / completed
127
127
  end
128
128
  end
129
129
  end
@@ -11,18 +11,18 @@ module Sidekiq
11
11
  #
12
12
  # # in your initializer
13
13
  # require "sidekiq/middleware/current_attributes"
14
- # Sidekiq::CurrentAttributes.persist(Myapp::Current)
14
+ # Sidekiq::CurrentAttributes.persist("Myapp::Current")
15
15
  #
16
16
  module CurrentAttributes
17
17
  class Save
18
18
  include Sidekiq::ClientMiddleware
19
19
 
20
20
  def initialize(cattr)
21
- @klass = cattr
21
+ @strklass = cattr
22
22
  end
23
23
 
24
24
  def call(_, job, _, _)
25
- attrs = @klass.attributes
25
+ attrs = @strklass.constantize.attributes
26
26
  if attrs.any?
27
27
  if job.has_key?("cattr")
28
28
  job["cattr"].merge!(attrs)
@@ -38,12 +38,12 @@ module Sidekiq
38
38
  include Sidekiq::ServerMiddleware
39
39
 
40
40
  def initialize(cattr)
41
- @klass = cattr
41
+ @strklass = cattr
42
42
  end
43
43
 
44
44
  def call(_, job, _, &block)
45
45
  if job.has_key?("cattr")
46
- @klass.set(job["cattr"], &block)
46
+ @strklass.constantize.set(job["cattr"], &block)
47
47
  else
48
48
  yield
49
49
  end
@@ -52,11 +52,11 @@ module Sidekiq
52
52
 
53
53
  def self.persist(klass)
54
54
  Sidekiq.configure_client do |config|
55
- config.client_middleware.add Save, klass
55
+ config.client_middleware.add Save, klass.to_s
56
56
  end
57
57
  Sidekiq.configure_server do |config|
58
- config.client_middleware.add Save, klass
59
- config.server_middleware.add Load, klass
58
+ config.client_middleware.add Save, klass.to_s
59
+ config.server_middleware.add Load, klass.to_s
60
60
  end
61
61
  end
62
62
  end
@@ -101,7 +101,7 @@ class Sidekiq::Monitor
101
101
  tags = [
102
102
  process["tag"],
103
103
  process["labels"],
104
- (process["quiet"] == "true" ? "quiet" : nil)
104
+ ((process["quiet"] == "true") ? "quiet" : nil)
105
105
  ].flatten.compact
106
106
  tags.any? ? "[#{tags.join("] [")}]" : nil
107
107
  end
@@ -3,7 +3,7 @@
3
3
  module Sidekiq
4
4
  module Paginator
5
5
  def page(key, pageidx = 1, page_size = 25, opts = nil)
6
- current_page = pageidx.to_i < 1 ? 1 : pageidx.to_i
6
+ current_page = (pageidx.to_i < 1) ? 1 : pageidx.to_i
7
7
  pageidx = current_page - 1
8
8
  total_size = 0
9
9
  items = []
@@ -43,5 +43,13 @@ module Sidekiq
43
43
  end
44
44
  end
45
45
  end
46
+
47
+ def page_items(items, pageidx = 1, page_size = 25)
48
+ current_page = (pageidx.to_i < 1) ? 1 : pageidx.to_i
49
+ pageidx = current_page - 1
50
+ starting = pageidx * page_size
51
+ items = items.to_a
52
+ [current_page, items.size, items[starting, page_size]]
53
+ end
46
54
  end
47
55
  end
data/lib/sidekiq/rails.rb CHANGED
@@ -37,17 +37,6 @@ module Sidekiq
37
37
  end
38
38
  end
39
39
 
40
- initializer "sidekiq.rails_logger" do
41
- Sidekiq.configure_server do |config|
42
- # This is the integration code necessary so that if a job uses `Rails.logger.info "Hello"`,
43
- # it will appear in the Sidekiq console with all of the job context. See #5021 and
44
- # https://github.com/rails/rails/blob/b5f2b550f69a99336482739000c58e4e04e033aa/railties/lib/rails/commands/server/server_command.rb#L82-L84
45
- unless ::Rails.logger == config.logger || ::ActiveSupport::Logger.logger_outputs_to?(::Rails.logger, $stdout)
46
- ::Rails.logger.extend(::ActiveSupport::Logger.broadcast(config.logger))
47
- end
48
- end
49
- end
50
-
51
40
  config.before_configuration do
52
41
  dep = ActiveSupport::Deprecation.new("7.0", "Sidekiq")
53
42
  dep.deprecate_methods(Sidekiq.singleton_class,
@@ -62,6 +51,16 @@ module Sidekiq
62
51
  config.after_initialize do
63
52
  Sidekiq.configure_server do |config|
64
53
  config[:reloader] = Sidekiq::Rails::Reloader.new
54
+
55
+ # This is the integration code necessary so that if a job uses `Rails.logger.info "Hello"`,
56
+ # it will appear in the Sidekiq console with all of the job context.
57
+ unless ::Rails.logger == config.logger || ::ActiveSupport::Logger.logger_outputs_to?(::Rails.logger, $stdout)
58
+ if ::Rails::VERSION::STRING < "7.1"
59
+ ::Rails.logger.extend(::ActiveSupport::Logger.broadcast(config.logger))
60
+ else
61
+ ::Rails.logger.broadcast_to(config.logger)
62
+ end
63
+ end
65
64
  end
66
65
  end
67
66
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sidekiq
4
- VERSION = "6.5.7"
4
+ VERSION = "6.5.12"
5
5
  end
@@ -74,6 +74,9 @@ module Sidekiq
74
74
  end
75
75
 
76
76
  get "/busy" do
77
+ @count = (params["count"] || 100).to_i
78
+ (@current_page, @total_size, @workset) = page_items(workset, params["page"], @count)
79
+
77
80
  erb(:busy)
78
81
  end
79
82
 
@@ -137,7 +137,7 @@ module Sidekiq
137
137
  end
138
138
 
139
139
  def sort_direction_label
140
- params[:direction] == "asc" ? "&uarr;" : "&darr;"
140
+ (params[:direction] == "asc") ? "&uarr;" : "&darr;"
141
141
  end
142
142
 
143
143
  def workset
@@ -148,25 +148,15 @@ module Sidekiq
148
148
  @processes ||= Sidekiq::ProcessSet.new
149
149
  end
150
150
 
151
- # Sorts processes by hostname following the natural sort order so that
152
- # 'worker.1' < 'worker.2' < 'worker.10' < 'worker.20'
153
- # '2.1.1.1' < '192.168.0.2' < '192.168.0.10'
151
+ # Sorts processes by hostname following the natural sort order
154
152
  def sorted_processes
155
153
  @sorted_processes ||= begin
156
154
  return processes unless processes.all? { |p| p["hostname"] }
157
155
 
158
- split_characters = /[._-]+/
159
-
160
- padding = processes.flat_map { |p| p["hostname"].split(split_characters) }.map(&:size).max
161
-
162
156
  processes.to_a.sort_by do |process|
163
- process["hostname"].split(split_characters).map do |substring|
164
- # Left-pad the substring with '0' if it starts with a number or 'a'
165
- # otherwise, so that '25' < 192' < 'a' ('025' < '192' < 'aaa')
166
- padding_char = substring[0].match?(/\d/) ? "0" : "a"
167
-
168
- substring.rjust(padding, padding_char)
169
- end
157
+ # Kudos to `shurikk` on StackOverflow
158
+ # https://stackoverflow.com/a/15170063/575547
159
+ process["hostname"].split(/(\d+)/).map { |a| /\d+/.match?(a) ? a.to_i : a }
170
160
  end
171
161
  end
172
162
  end
@@ -198,7 +188,7 @@ module Sidekiq
198
188
  end
199
189
 
200
190
  def current_status
201
- workset.size == 0 ? "idle" : "active"
191
+ (workset.size == 0) ? "idle" : "active"
202
192
  end
203
193
 
204
194
  def relative_time(time)
@@ -231,7 +221,7 @@ module Sidekiq
231
221
  end
232
222
 
233
223
  def truncate(text, truncate_after_chars = 2000)
234
- truncate_after_chars && text.size > truncate_after_chars ? "#{text[0..truncate_after_chars]}..." : text
224
+ (truncate_after_chars && text.size > truncate_after_chars) ? "#{text[0..truncate_after_chars]}..." : text
235
225
  end
236
226
 
237
227
  def display_args(args, truncate_after_chars = 2000)
@@ -257,7 +257,7 @@ module Sidekiq
257
257
  def at(interval)
258
258
  int = interval.to_f
259
259
  now = Time.now.to_f
260
- ts = (int < 1_000_000_000 ? now + int : int)
260
+ ts = ((int < 1_000_000_000) ? now + int : int)
261
261
  # Optimization to enqueue something now that is scheduled to go out now or in the past
262
262
  @opts["at"] = ts if ts > now
263
263
  self
@@ -324,7 +324,7 @@ module Sidekiq
324
324
  def perform_in(interval, *args)
325
325
  int = interval.to_f
326
326
  now = Time.now.to_f
327
- ts = (int < 1_000_000_000 ? now + int : int)
327
+ ts = ((int < 1_000_000_000) ? now + int : int)
328
328
 
329
329
  item = {"class" => self, "args" => args}
330
330
 
data/sidekiq.gemspec CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |gem|
22
22
  "source_code_uri" => "https://github.com/mperham/sidekiq"
23
23
  }
24
24
 
25
- gem.add_dependency "redis", "<5", ">= 4.5.0"
26
- gem.add_dependency "connection_pool", ">= 2.2.5"
25
+ gem.add_dependency "redis", ["<5", ">= 4.5.0"]
26
+ gem.add_dependency "connection_pool", ["<3", ">= 2.2.5"]
27
27
  gem.add_dependency "rack", "~> 2.0"
28
28
  end
@@ -122,6 +122,7 @@ function checkResponse(resp) {
122
122
 
123
123
  function scheduleLivePoll() {
124
124
  let ti = parseInt(localStorage.sidekiqTimeInterval) || 5000;
125
+ if (ti < 2000) { ti = 2000 }
125
126
  livePollTimer = setTimeout(livePollCallback, ti);
126
127
  }
127
128
 
data/web/views/busy.erb CHANGED
@@ -96,6 +96,11 @@
96
96
  <div class="col-sm-7">
97
97
  <h3><%= t('Jobs') %></h3>
98
98
  </div>
99
+ <% if @workset.size > 0 && @total_size > @count %>
100
+ <div class="col-sm-4">
101
+ <%= erb :_paging, locals: { url: "#{root_path}busy" } %>
102
+ </div>
103
+ <% end %>
99
104
  </div>
100
105
 
101
106
  <div class="table_container">
@@ -109,7 +114,7 @@
109
114
  <th><%= t('Arguments') %></th>
110
115
  <th><%= t('Started') %></th>
111
116
  </thead>
112
- <% workset.each do |process, thread, msg| %>
117
+ <% @workset.each do |process, thread, msg| %>
113
118
  <% job = Sidekiq::JobRecord.new(msg['payload']) %>
114
119
  <tr>
115
120
  <td><%= process %></td>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.5.7
4
+ version: 6.5.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Perham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-20 00:00:00.000000000 Z
11
+ date: 2023-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -34,6 +34,9 @@ dependencies:
34
34
  name: connection_pool
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
+ - - "<"
38
+ - !ruby/object:Gem::Version
39
+ version: '3'
37
40
  - - ">="
38
41
  - !ruby/object:Gem::Version
39
42
  version: 2.2.5
@@ -41,6 +44,9 @@ dependencies:
41
44
  prerelease: false
42
45
  version_requirements: !ruby/object:Gem::Requirement
43
46
  requirements:
47
+ - - "<"
48
+ - !ruby/object:Gem::Version
49
+ version: '3'
44
50
  - - ">="
45
51
  - !ruby/object:Gem::Version
46
52
  version: 2.2.5
@@ -212,7 +218,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
212
218
  - !ruby/object:Gem::Version
213
219
  version: '0'
214
220
  requirements: []
215
- rubygems_version: 3.2.32
221
+ rubygems_version: 3.4.20
216
222
  signing_key:
217
223
  specification_version: 4
218
224
  summary: Simple, efficient background processing for Ruby