sidekiq 8.0.3 → 8.0.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5862bbba5b859c1983788b6aeb49193fad724a1186426084c1e42747cb226ba2
4
- data.tar.gz: 11fbaba14b814b87d09d809173ca59f9477c119f9ab6d556e4a9baa8e4e83d63
3
+ metadata.gz: c6b95635fb1084ed28d8b6dd5f7d273873e24ffab09aeb5057de74d4bebeae07
4
+ data.tar.gz: bba44aed090637fb4991ae3935112b84b33df8b7281c9d0f273f0146ea11415a
5
5
  SHA512:
6
- metadata.gz: 67d640ff21778c036ba15db434bafe0582a61e1b462d1bee2502fa7a9b8978208b4099c46d8ad6bd6214f198558de8985deeb11b6e7d99f1e603b15f087f0215
7
- data.tar.gz: 4becc4ea36c062f52667fea91d4f49b5bfb759fe43f75ef6427c1aeacdc36764408f442cafccc3595585cf13ef2ff71da98212d7db0fcb89ff198ace0cd19caa
6
+ metadata.gz: 657b2d2f1e1c850779d29990c88227d7776f8e5a4b3333fd7b2e5f249fb360a1f69de40a773dc5b608ae37ff249713af5aa5b38cd04da2ceffe64f79578861a3
7
+ data.tar.gz: a8d8d6f32921b00341dc8910155b8a85d6c036bc31a69437dde3f5107d02bed5ffb2b0754f014eaf69f577570e91455a7ead03367cf43fe0b24ef2650e9f57be
data/Changes.md CHANGED
@@ -2,7 +2,27 @@
2
2
 
3
3
  [Sidekiq Changes](https://github.com/sidekiq/sidekiq/blob/main/Changes.md) | [Sidekiq Pro Changes](https://github.com/sidekiq/sidekiq/blob/main/Pro-Changes.md) | [Sidekiq Enterprise Changes](https://github.com/sidekiq/sidekiq/blob/main/Ent-Changes.md)
4
4
 
5
- HEAD
5
+ 8.0.5
6
+ ----------
7
+
8
+ - Add `stopping?` method to AJ adapter for compatibility with the new AJ::Continuations feature [#6732]
9
+ - Further improvements to Rails boot compatibility [#6710]
10
+ - Add ability to disable CSRF middleware. SameSite cookies prevent
11
+ CSRF in a cleaner manner and are default in most browsers now.
12
+ CSRF code will be removed in Sidekiq 9.0. [#6739]
13
+
14
+ 8.0.4
15
+ ----------
16
+
17
+ - Adjust Rails integration for various edge cases [6713]
18
+ - Flush job iteration state when an error is raised [#6704]
19
+ - Update Accept-Language parsing in Web UI [#6721]
20
+ - Remove fixed-width in Web UI [#6686]
21
+ - Adjust CSRF middleware ordering [#6688]
22
+ - Support proxies when POSTing profiles to profiler.firefox.com [#6687]
23
+ - Dont swallow NoMethodErrors in CurrentAttributes [#6685]
24
+
25
+ 8.0.3
6
26
  ----------
7
27
 
8
28
  - Configure Vernier output directory [#6674]
@@ -17,7 +17,7 @@ begin
17
17
  end
18
18
  end
19
19
 
20
- unless ActiveJob::Base.respond_to?(:sidekiq_options)
20
+ ActiveSupport.on_load(:active_job) do
21
21
  # By including the Options module, we allow AJs to directly control sidekiq features
22
22
  # via the *sidekiq_options* class method and, for instance, not use AJ's retry system.
23
23
  # AJ retries don't show up in the Sidekiq UI Retries tab, don't save any error data, can't be
@@ -29,7 +29,7 @@ begin
29
29
  # def perform
30
30
  # end
31
31
  # end
32
- ActiveJob::Base.include Sidekiq::Job::Options
32
+ include Sidekiq::Job::Options unless respond_to?(:sidekiq_options)
33
33
  end
34
34
 
35
35
  # Patch the ActiveJob module
@@ -43,7 +43,14 @@ begin
43
43
  # To use Sidekiq set the queue_adapter config to +:sidekiq+.
44
44
  #
45
45
  # Rails.application.config.active_job.queue_adapter = :sidekiq
46
- class SidekiqAdapter
46
+ class SidekiqAdapter < AbstractAdapter
47
+ @@stopping = false
48
+
49
+ callback = -> { @@stopping = true }
50
+
51
+ Sidekiq.configure_client { |config| config.on(:quiet, &callback) }
52
+ Sidekiq.configure_server { |config| config.on(:quiet, &callback) }
53
+
47
54
  # Defines whether enqueuing should happen implicitly to after commit when called
48
55
  # from inside a transaction.
49
56
  # @api private
@@ -99,10 +106,12 @@ begin
99
106
  enqueued_count
100
107
  end
101
108
 
109
+ # @api private
110
+ def stopping? = !!@@stopping
111
+
102
112
  # Defines a class alias for backwards compatibility with enqueued Active Job jobs.
103
113
  # @api private
104
- class JobWrapper < Sidekiq::ActiveJob::Wrapper
105
- end
114
+ JobWrapper = Sidekiq::ActiveJob::Wrapper
106
115
  end
107
116
  end
108
117
  end
@@ -221,6 +221,9 @@ module Sidekiq
221
221
  verify_iteration_time(time_limit, object) do
222
222
  around_iteration do
223
223
  each_iteration(object, *arguments)
224
+ rescue Exception
225
+ flush_state
226
+ raise
224
227
  end
225
228
  end
226
229
  end
@@ -71,11 +71,14 @@ module Sidekiq
71
71
  retried = false
72
72
 
73
73
  begin
74
+ set_succeeded = false
74
75
  klass.set(attrs) do
76
+ set_succeeded = true
75
77
  wrap(klass_attrs, &block)
76
78
  end
77
79
  rescue NoMethodError
78
- raise if retried
80
+ # Don't retry if the no method error didn't come from current attributes
81
+ raise if retried || set_succeeded
79
82
 
80
83
  # It is possible that the `CurrentAttributes` definition
81
84
  # was changed before the job started processing.
data/lib/sidekiq/rails.rb CHANGED
@@ -1,12 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "sidekiq/job"
4
- require_relative "../active_job/queue_adapters/sidekiq_adapter"
5
-
6
3
  module Sidekiq
7
4
  begin
8
5
  gem "railties", ">= 7.0"
9
6
  require "rails"
7
+ require "sidekiq/job"
8
+ require_relative "../active_job/queue_adapters/sidekiq_adapter"
10
9
 
11
10
  class Rails < ::Rails::Engine
12
11
  class Reloader
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sidekiq
4
- VERSION = "8.0.3"
4
+ VERSION = "8.0.5"
5
5
  MAJOR = 8
6
6
 
7
7
  def self.gem_version
@@ -325,6 +325,8 @@ module Sidekiq
325
325
  get "/stats" do
326
326
  sidekiq_stats = Sidekiq::Stats.new
327
327
  redis_stats = redis_info.slice(*REDIS_KEYS)
328
+ redis_stats["store_name"] = store_name
329
+ redis_stats["store_version"] = store_version
328
330
  json(
329
331
  sidekiq: {
330
332
  processed: sidekiq_stats.processed,
@@ -360,10 +362,16 @@ module Sidekiq
360
362
  unless sid
361
363
  require "net/http"
362
364
  data = Sidekiq.redis { |c| c.hget(key, "data") }
363
- resp = Net::HTTP.post(URI(store),
364
- data,
365
- {"Accept" => "application/vnd.firefox-profiler+json;version=1.0",
366
- "User-Agent" => "Sidekiq #{Sidekiq::VERSION} job profiler"})
365
+
366
+ store_uri = URI(store)
367
+ http = Net::HTTP.new(store_uri.host, store_uri.port)
368
+ http.use_ssl = store_uri.scheme == "https"
369
+ request = Net::HTTP::Post.new(store_uri.request_uri)
370
+ request.body = data
371
+ request["Accept"] = "application/vnd.firefox-profiler+json;version=1.0"
372
+ request["User-Agent"] = "Sidekiq #{Sidekiq::VERSION} job profiler"
373
+
374
+ resp = http.request(request)
367
375
  # https://raw.githubusercontent.com/firefox-devtools/profiler-server/master/tools/decode_jwt_payload.py
368
376
  rawjson = resp.body.split(".")[1].unpack1("m")
369
377
  sid = Sidekiq.load_json(rawjson)["profileToken"]
@@ -24,7 +24,10 @@ module Sidekiq
24
24
  # and very difficult for us to vendor or provide ourselves. If you are worried
25
25
  # about data security and wish to self-host, you can change these URLs.
26
26
  profile_view_url: "https://profiler.firefox.com/public/%s",
27
- profile_store_url: "https://api.profiler.firefox.com/compressed-store"
27
+ profile_store_url: "https://api.profiler.firefox.com/compressed-store",
28
+ # Will be false in Sidekiq 9.0.
29
+ # CSRF is unnecessary if you are using SameSite=(Strict|Lax) cookies.
30
+ csrf: true
28
31
  }
29
32
 
30
33
  ##
@@ -57,7 +60,7 @@ module Sidekiq
57
60
  @locales = LOCALES
58
61
  @views = VIEWS
59
62
  @tabs = DEFAULT_TABS.dup
60
- @middlewares = [Sidekiq::Web::CsrfProtection]
63
+ @middlewares = []
61
64
  @custom_job_info_rows = []
62
65
  end
63
66
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "uri"
4
4
  require "yaml"
5
- require "cgi"
5
+ require "cgi/escape"
6
6
 
7
7
  module Sidekiq
8
8
  # These methods are available to pages within the Web UI and UI extensions.
@@ -165,7 +165,10 @@ module Sidekiq
165
165
  text_direction == "rtl"
166
166
  end
167
167
 
168
- # See https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
168
+ # See https://www.rfc-editor.org/rfc/rfc9110.html#section-12.5.4
169
+ # Returns an array of language tags ordered by their quality value
170
+ #
171
+ # Inspiration taken from https://github.com/iain/http_accept_language/blob/master/lib/http_accept_language/parser.rb
169
172
  def user_preferred_languages
170
173
  languages = env["HTTP_ACCEPT_LANGUAGE"]
171
174
  languages.to_s.gsub(/\s+/, "").split(",").map { |language|
@@ -180,28 +183,30 @@ module Sidekiq
180
183
 
181
184
  # Given an Accept-Language header like "fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,ru;q=0.2"
182
185
  # this method will try to best match the available locales to the user's preferred languages.
183
- #
184
- # Inspiration taken from https://github.com/iain/http_accept_language/blob/master/lib/http_accept_language/parser.rb
185
186
  def locale
186
187
  # session[:locale] is set via the locale selector from the footer
187
188
  @locale ||= if (l = session&.fetch(:locale, nil)) && available_locales.include?(l)
188
189
  l
189
190
  else
191
+ matched_locale = nil
192
+ # Attempt to find a case-insensitive exact match first
193
+ user_preferred_languages.each do |preferred|
194
+ # We only care about the language and primary subtag
195
+ # "en-GB-oxendict" becomes "en-GB"
196
+ language_tag = preferred.split("-")[0..1].join("-")
197
+ matched_locale = available_locales.find { |available_locale| available_locale.casecmp?(language_tag) }
198
+ break if matched_locale
199
+ end
190
200
 
191
- # exactly match with preferred like "pt-BR, zh-CN, zh-TW..." first
192
- matched_locale = user_preferred_languages.find { |preferred|
193
- available_locales.include?(preferred) if preferred.length == 5
194
- }
195
-
196
- matched_locale ||= user_preferred_languages.map { |preferred|
197
- preferred_language = preferred.split("-", 2).first
198
-
199
- lang_group = available_locales.select { |available|
200
- preferred_language == available.split("-", 2).first
201
- }
201
+ return matched_locale if matched_locale
202
202
 
203
- lang_group.find { |lang| lang == preferred } || lang_group.min_by(&:length)
204
- }.compact.first
203
+ # Find the first base language match
204
+ # "en-US,es-MX;q=0.9" matches "en"
205
+ user_preferred_languages.each do |preferred|
206
+ base_language = preferred.split("-", 2).first
207
+ matched_locale = available_locales.find { |available_locale| available_locale.casecmp?(base_language) }
208
+ break if matched_locale
209
+ end
205
210
 
206
211
  matched_locale || "en"
207
212
  end
@@ -372,7 +377,7 @@ module Sidekiq
372
377
  elsif rss_kb < 10_000_000
373
378
  "#{number_with_delimiter((rss_kb / 1024.0).to_i)} MB"
374
379
  else
375
- "#{number_with_delimiter((rss_kb / (1024.0 * 1024.0)), precision: 1)} GB"
380
+ "#{number_with_delimiter(rss_kb / (1024.0 * 1024.0), precision: 1)} GB"
376
381
  end
377
382
  end
378
383
 
data/lib/sidekiq/web.rb CHANGED
@@ -109,6 +109,7 @@ module Sidekiq
109
109
  cascade: true,
110
110
  header_rules: rules
111
111
  m.each { |middleware, block| use(*middleware, &block) }
112
+ use CsrfProtection if cfg[:csrf]
112
113
  run Sidekiq::Web::Application.new(self.class)
113
114
  end
114
115
  end
data/lib/sidekiq.rb CHANGED
@@ -146,4 +146,4 @@ module Sidekiq
146
146
  class Shutdown < Interrupt; end
147
147
  end
148
148
 
149
- require "sidekiq/rails"
149
+ require "sidekiq/rails" if defined?(::Rails::Engine)
@@ -11,7 +11,7 @@ var updateStatsSummary = function(data) {
11
11
  }
12
12
 
13
13
  var updateRedisStats = function(data) {
14
- document.getElementById('redis_version').innerText = data.redis_version;
14
+ document.getElementById('redis_version').innerText = data.store_version;
15
15
  document.getElementById('uptime_in_days').innerText = data.uptime_in_days;
16
16
  document.getElementById('connected_clients').innerText = data.connected_clients;
17
17
  document.getElementById('used_memory_human').innerText = data.used_memory_human;
@@ -69,7 +69,7 @@ body {
69
69
 
70
70
  .container {
71
71
  margin: 0 auto;
72
- max-width: 1440px;
72
+ /* max-width: 1440px; */
73
73
  padding: var(--space-2x);
74
74
  }
75
75
 
@@ -90,6 +90,7 @@ code {
90
90
  font-family: var(--font-mono);
91
91
  font-size: var(--font-size-small);
92
92
  padding: var(--space-1-2);
93
+ word-wrap: anywhere;
93
94
  }
94
95
 
95
96
  time { color: var(--color-text-light); }
@@ -437,7 +438,10 @@ article .count {
437
438
  }
438
439
 
439
440
  /* table */
440
- .table_container { overflow-x: auto; }
441
+ .table_container {
442
+ overflow-x: auto;
443
+ margin-bottom: var(--space-2x);
444
+ }
441
445
 
442
446
  .table_container + form,
443
447
  .table_container + input,
@@ -563,6 +567,7 @@ body > footer .nav {
563
567
  --color-border: oklch(25% 0.01 256);
564
568
  --color-input-border: oklch(31% 0.01 256);
565
569
  --color-selected: oklch(27% 0.01 256);
570
+ --color-selected-text: oklch(55% 0.11 45);
566
571
  --color-table-bg-alt: oklch(24% 0.01 256);
567
572
  --color-shadow: oklch(9% 0.01 256 / 10%);
568
573
  --color-text: oklch(75% 0.01 256);
@@ -611,6 +616,10 @@ body > footer .nav {
611
616
  .label-info { background: var(--color-info); }
612
617
  .label-danger { background: var(--color-danger); }
613
618
  .label-warning { background: var(--color-warning); }
619
+
620
+ td.box::selection {
621
+ background-color: var(--color-selected-text);
622
+ }
614
623
  }
615
624
 
616
625
  @media (max-width: 800px) { :root { --font-size: 14px; } }
@@ -754,4 +763,4 @@ body > footer .nav {
754
763
  text-align: center;
755
764
  padding: 20px;
756
765
  background: var(--color-success);
757
- }
766
+ }
@@ -57,4 +57,4 @@
57
57
  <% else %>
58
58
  <div class="alert alert-success"><%= t('NoScheduledFound') %></div>
59
59
  <% end %>
60
- </div>
60
+ </section>
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.0.3
4
+ version: 8.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Perham
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-04-24 00:00:00.000000000 Z
10
+ date: 2025-06-30 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: redis-client