sidekiq 7.2.4 → 7.3.1

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +43 -0
  3. data/README.md +1 -1
  4. data/lib/generators/sidekiq/job_generator.rb +2 -0
  5. data/lib/sidekiq/api.rb +10 -4
  6. data/lib/sidekiq/capsule.rb +5 -0
  7. data/lib/sidekiq/cli.rb +1 -0
  8. data/lib/sidekiq/client.rb +4 -1
  9. data/lib/sidekiq/config.rb +7 -1
  10. data/lib/sidekiq/deploy.rb +2 -0
  11. data/lib/sidekiq/embedded.rb +2 -0
  12. data/lib/sidekiq/fetch.rb +1 -1
  13. data/lib/sidekiq/iterable_job.rb +55 -0
  14. data/lib/sidekiq/job/interrupt_handler.rb +24 -0
  15. data/lib/sidekiq/job/iterable/active_record_enumerator.rb +53 -0
  16. data/lib/sidekiq/job/iterable/csv_enumerator.rb +47 -0
  17. data/lib/sidekiq/job/iterable/enumerators.rb +135 -0
  18. data/lib/sidekiq/job/iterable.rb +231 -0
  19. data/lib/sidekiq/job.rb +13 -2
  20. data/lib/sidekiq/job_logger.rb +22 -11
  21. data/lib/sidekiq/job_retry.rb +6 -1
  22. data/lib/sidekiq/job_util.rb +2 -0
  23. data/lib/sidekiq/metrics/query.rb +2 -0
  24. data/lib/sidekiq/metrics/shared.rb +2 -0
  25. data/lib/sidekiq/metrics/tracking.rb +13 -5
  26. data/lib/sidekiq/middleware/current_attributes.rb +29 -11
  27. data/lib/sidekiq/middleware/modules.rb +2 -0
  28. data/lib/sidekiq/monitor.rb +2 -1
  29. data/lib/sidekiq/processor.rb +11 -1
  30. data/lib/sidekiq/redis_client_adapter.rb +8 -5
  31. data/lib/sidekiq/redis_connection.rb +33 -2
  32. data/lib/sidekiq/ring_buffer.rb +2 -0
  33. data/lib/sidekiq/systemd.rb +2 -0
  34. data/lib/sidekiq/version.rb +1 -1
  35. data/lib/sidekiq/web/action.rb +2 -1
  36. data/lib/sidekiq/web/application.rb +9 -4
  37. data/lib/sidekiq/web/helpers.rb +53 -7
  38. data/lib/sidekiq/web.rb +48 -1
  39. data/lib/sidekiq.rb +2 -1
  40. data/sidekiq.gemspec +2 -1
  41. data/web/assets/javascripts/application.js +6 -1
  42. data/web/assets/javascripts/dashboard-charts.js +22 -12
  43. data/web/assets/javascripts/dashboard.js +1 -1
  44. data/web/assets/stylesheets/application.css +13 -1
  45. data/web/locales/tr.yml +101 -0
  46. data/web/views/dashboard.erb +6 -6
  47. data/web/views/layout.erb +6 -6
  48. data/web/views/metrics.erb +4 -4
  49. data/web/views/metrics_for_job.erb +4 -4
  50. metadata +26 -5
@@ -6,8 +6,51 @@ require "yaml"
6
6
  require "cgi"
7
7
 
8
8
  module Sidekiq
9
- # This is not a public API
9
+ # These methods are available to pages within the Web UI and UI extensions.
10
+ # They are not public APIs for applications to use.
10
11
  module WebHelpers
12
+ def style_tag(location, **kwargs)
13
+ global = location.match?(/:\/\//)
14
+ location = root_path + location if !global && !location.start_with?(root_path)
15
+ attrs = {
16
+ type: "text/css",
17
+ media: "screen",
18
+ rel: "stylesheet",
19
+ nonce: csp_nonce,
20
+ href: location
21
+ }
22
+ html_tag(:link, attrs.merge(kwargs))
23
+ end
24
+
25
+ def script_tag(location, **kwargs)
26
+ global = location.match?(/:\/\//)
27
+ location = root_path + location if !global && !location.start_with?(root_path)
28
+ attrs = {
29
+ type: "text/javascript",
30
+ nonce: csp_nonce,
31
+ src: location
32
+ }
33
+ html_tag(:script, attrs.merge(kwargs)) {}
34
+ end
35
+
36
+ # NB: keys and values are not escaped; do not allow user input
37
+ # in the attributes
38
+ private def html_tag(tagname, attrs)
39
+ s = +"<#{tagname}"
40
+ attrs.each_pair do |k, v|
41
+ next unless v
42
+ s << " #{k}=\"#{v}\""
43
+ end
44
+ if block_given?
45
+ s << ">"
46
+ yield s
47
+ s << "</#{tagname}>"
48
+ else
49
+ s << " />"
50
+ end
51
+ s
52
+ end
53
+
11
54
  def strings(lang)
12
55
  @strings ||= {}
13
56
 
@@ -46,7 +89,7 @@ module Sidekiq
46
89
  end
47
90
 
48
91
  def available_locales
49
- @available_locales ||= locale_files.map { |path| File.basename(path, ".yml") }.uniq
92
+ @available_locales ||= Set.new(locale_files.map { |path| File.basename(path, ".yml") })
50
93
  end
51
94
 
52
95
  def find_locale_files(lang)
@@ -122,10 +165,9 @@ module Sidekiq
122
165
  # Inspiration taken from https://github.com/iain/http_accept_language/blob/master/lib/http_accept_language/parser.rb
123
166
  def locale
124
167
  # session[:locale] is set via the locale selector from the footer
125
- # defined?(session) && session are used to avoid exceptions when running tests
126
- return session[:locale] if defined?(session) && session&.[](:locale)
127
-
128
- @locale ||= begin
168
+ @locale ||= if (l = session&.fetch(:locale, nil)) && available_locales.include?(l)
169
+ l
170
+ else
129
171
  matched_locale = user_preferred_languages.map { |preferred|
130
172
  preferred_language = preferred.split("-", 2).first
131
173
 
@@ -267,6 +309,10 @@ module Sidekiq
267
309
  "<input type='hidden' name='authenticity_token' value='#{env[:csrf_token]}'/>"
268
310
  end
269
311
 
312
+ def csp_nonce
313
+ env[:csp_nonce]
314
+ end
315
+
270
316
  def to_display(arg)
271
317
  arg.inspect
272
318
  rescue
@@ -310,7 +356,7 @@ module Sidekiq
310
356
  end
311
357
 
312
358
  def h(text)
313
- ::Rack::Utils.escape_html(text)
359
+ ::Rack::Utils.escape_html(text.to_s)
314
360
  rescue ArgumentError => e
315
361
  raise unless e.message.eql?("invalid byte sequence in UTF-8")
316
362
  text.encode!("UTF-16", "UTF-8", invalid: :replace, replace: "").encode!("UTF-8", "UTF-16")
data/lib/sidekiq/web.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "erb"
4
+ require "securerandom"
4
5
 
5
6
  require "sidekiq"
6
7
  require "sidekiq/api"
@@ -39,11 +40,13 @@ module Sidekiq
39
40
  CONTENT_SECURITY_POLICY = "Content-Security-Policy"
40
41
  LOCATION = "Location"
41
42
  X_CASCADE = "X-Cascade"
43
+ X_CONTENT_TYPE_OPTIONS = "X-Content-Type-Options"
42
44
  else
43
45
  CONTENT_LANGUAGE = "content-language"
44
46
  CONTENT_SECURITY_POLICY = "content-security-policy"
45
47
  LOCATION = "location"
46
48
  X_CASCADE = "x-cascade"
49
+ X_CONTENT_TYPE_OPTIONS = "x-content-type-options"
47
50
  end
48
51
 
49
52
  class << self
@@ -114,6 +117,7 @@ module Sidekiq
114
117
  end
115
118
 
116
119
  def call(env)
120
+ env[:csp_nonce] = SecureRandom.base64(16)
117
121
  app.call(env)
118
122
  end
119
123
 
@@ -138,7 +142,50 @@ module Sidekiq
138
142
  send(:"#{attribute}=", value)
139
143
  end
140
144
 
141
- def self.register(extension)
145
+ # Register a class as a Sidekiq Web UI extension. The class should
146
+ # provide one or more tabs which map to an index route. Options:
147
+ #
148
+ # @param extension [Class] Class which contains the HTTP actions, required
149
+ # @param name [String] the name of the extension, used to namespace assets
150
+ # @param tab [String | Array] labels(s) of the UI tabs
151
+ # @param index [String | Array] index route(s) for each tab
152
+ # @param root_dir [String] directory location to find assets, locales and views, typically `web/` within the gemfile
153
+ # @param asset_paths [Array] one or more directories under {root}/assets/{name} to be publicly served, e.g. ["js", "css", "img"]
154
+ # @param cache_for [Integer] amount of time to cache assets, default one day
155
+ #
156
+ # TODO name, tab and index will be mandatory in 8.0
157
+ #
158
+ # Web extensions will have a root `web/` directory with `locales/`, `assets/`
159
+ # and `views/` subdirectories.
160
+ def self.register(extension, name: nil, tab: nil, index: nil, root_dir: nil, cache_for: 86400, asset_paths: nil)
161
+ tab = Array(tab)
162
+ index = Array(index)
163
+ tab.zip(index).each do |tab, index|
164
+ tabs[tab] = index
165
+ end
166
+ if root_dir
167
+ locdir = File.join(root_dir, "locales")
168
+ locales << locdir if File.directory?(locdir)
169
+
170
+ if asset_paths && name
171
+ # if you have {root}/assets/{name}/js/scripts.js
172
+ # and {root}/assets/{name}/css/styles.css
173
+ # you would pass in:
174
+ # asset_paths: ["js", "css"]
175
+ # See script_tag and style_tag in web/helpers.rb
176
+ assdir = File.join(root_dir, "assets")
177
+ assurls = Array(asset_paths).map { |x| "/#{name}/#{x}" }
178
+ assetprops = {
179
+ urls: assurls,
180
+ root: assdir,
181
+ cascade: true
182
+ }
183
+ assetprops[:header_rules] = [[:all, {Rack::CACHE_CONTROL => "private, max-age=#{cache_for.to_i}"}]] if cache_for
184
+ middlewares << [[Rack::Static, assetprops], nil]
185
+ end
186
+ end
187
+
188
+ yield self if block_given?
142
189
  extension.registered(WebApplication)
143
190
  end
144
191
 
data/lib/sidekiq.rb CHANGED
@@ -32,6 +32,7 @@ require "sidekiq/logger"
32
32
  require "sidekiq/client"
33
33
  require "sidekiq/transaction_aware_client"
34
34
  require "sidekiq/job"
35
+ require "sidekiq/iterable_job"
35
36
  require "sidekiq/worker_compatibility_alias"
36
37
  require "sidekiq/redis_client_adapter"
37
38
 
@@ -112,7 +113,7 @@ module Sidekiq
112
113
  # end
113
114
  # inst.run
114
115
  # sleep 10
115
- # inst.terminate
116
+ # inst.stop
116
117
  #
117
118
  # NB: it is really easy to overload a Ruby process with threads due to the GIL.
118
119
  # I do not recommend setting concurrency higher than 2-3.
data/sidekiq.gemspec CHANGED
@@ -23,8 +23,9 @@ Gem::Specification.new do |gem|
23
23
  "rubygems_mfa_required" => "true"
24
24
  }
25
25
 
26
- gem.add_dependency "redis-client", ">= 0.19.0"
26
+ gem.add_dependency "redis-client", ">= 0.22.2"
27
27
  gem.add_dependency "connection_pool", ">= 2.3.0"
28
28
  gem.add_dependency "rack", ">= 2.2.4"
29
29
  gem.add_dependency "concurrent-ruby", "< 2"
30
+ gem.add_dependency "logger"
30
31
  end
@@ -34,6 +34,7 @@ function addListeners() {
34
34
  addShiftClickListeners()
35
35
  updateFuzzyTimes();
36
36
  updateNumbers();
37
+ updateProgressBars();
37
38
  setLivePollFromUrl();
38
39
 
39
40
  var buttons = document.querySelectorAll(".live-poll");
@@ -180,4 +181,8 @@ function showError(error) {
180
181
 
181
182
  function updateLocale(event) {
182
183
  event.target.form.submit();
183
- };
184
+ }
185
+
186
+ function updateProgressBars() {
187
+ document.querySelectorAll('.progress-bar').forEach(bar => { bar.style.width = bar.dataset.width + "%"})
188
+ }
@@ -108,17 +108,27 @@ class RealtimeChart extends DashboardChart {
108
108
  }
109
109
 
110
110
  renderLegend(dp) {
111
- this.legend.innerHTML = `
112
- <span>
113
- <span class="swatch" style="background-color: ${dp[0].dataset.borderColor};"></span>
114
- <span>${dp[0].dataset.label}: ${dp[0].formattedValue}</span>
115
- </span>
116
- <span>
117
- <span class="swatch" style="background-color: ${dp[1].dataset.borderColor};"></span>
118
- <span>${dp[1].dataset.label}: ${dp[1].formattedValue}</span>
119
- </span>
120
- <span class="time">${dp[0].label}</span>
121
- `;
111
+ const entry1 = this.legendEntry(dp[0]);
112
+ const entry2 = this.legendEntry(dp[1]);
113
+ const time = document.createElement("span");
114
+ time.classList.add("time");
115
+ time.innerText = dp[0].label;
116
+
117
+ this.legend.replaceChildren(entry1, entry2, time)
118
+ }
119
+
120
+ legendEntry(dp) {
121
+ const wrapper = document.createElement("span");
122
+
123
+ const swatch = document.createElement("span");
124
+ swatch.classList.add("swatch");
125
+ swatch.style.backgroundColor = dp.dataset.borderColor;
126
+ wrapper.appendChild(swatch)
127
+
128
+ const label = document.createElement("span");
129
+ label.innerText = `${dp.dataset.label}: ${dp.formattedValue}`;
130
+ wrapper.appendChild(label)
131
+ return wrapper;
122
132
  }
123
133
 
124
134
  renderCursor(dp) {
@@ -179,4 +189,4 @@ class RealtimeChart extends DashboardChart {
179
189
  if (hc != null) {
180
190
  var htc = new DashboardChart(hc, JSON.parse(hc.textContent))
181
191
  window.historyChart = htc
182
- }
192
+ }
@@ -28,7 +28,7 @@ var pulseBeacon = function() {
28
28
  }
29
29
 
30
30
  var setSliderLabel = function(val) {
31
- document.getElementById('sldr-text').innerText = Math.round(parseFloat(val) / 1000) + ' sec';
31
+ document.getElementById('sldr-text').innerText = Math.round(parseFloat(val) / 1000) + ' s';
32
32
  }
33
33
 
34
34
  var ready = (callback) => {
@@ -72,6 +72,14 @@ h1, h2, h3 {
72
72
  line-height: 45px;
73
73
  }
74
74
 
75
+ .progress {
76
+ margin-bottom: 0;
77
+ }
78
+
79
+ .w-50 {
80
+ width: 50%;
81
+ }
82
+
75
83
  .header-container, .header-container .page-title-container {
76
84
  display: flex;
77
85
  justify-content: space-between;
@@ -626,8 +634,12 @@ div.interval-slider input {
626
634
  .container {
627
635
  padding: 0;
628
636
  }
637
+ .navbar-fixed-bottom {
638
+ position: relative;
639
+ top: auto;
640
+ }
629
641
  @media (max-width: 767px) {
630
- .navbar-fixed-top, .navbar-fixed-bottom {
642
+ .navbar-fixed-top {
631
643
  position: relative;
632
644
  top: auto;
633
645
  }
@@ -0,0 +1,101 @@
1
+ # elements like %{queue} are variables and should not be translated
2
+ tr:
3
+ Actions: Eylemler
4
+ AddToQueue: Kuyruğa ekle
5
+ AreYouSure: Emin misiniz?
6
+ AreYouSureDeleteJob: Bu işi silmek istediğinizden emin misiniz?
7
+ AreYouSureDeleteQueue: "%{queue} kuyruğunu silmek istediğinizden emin misiniz?"
8
+ Arguments: Argümanlar
9
+ BackToApp: Uygulamaya geri dön
10
+ Busy: Meşgul
11
+ Class: Sınıf
12
+ Connections: Bağlantılar
13
+ CreatedAt: Oluşturulma Tarihi
14
+ CurrentMessagesInQueue: Şu anki işler <span class='title'>%{queue}</span>
15
+ Dashboard: Gösterge Paneli
16
+ Dead: Ölü
17
+ DeadJobs: Ölü İşler
18
+ Delete: Sil
19
+ DeleteAll: Hepsini Sil
20
+ Deploy: Dağıt
21
+ Enqueued: Kuyruğa Alındı
22
+ Error: Hata
23
+ ErrorBacktrace: Hata Geri İzleme
24
+ ErrorClass: Hata Sınıfı
25
+ ErrorMessage: Hata Mesajı
26
+ ExecutionTime: Yürütme Süresi
27
+ Extras: Ekstralar
28
+ Failed: Başarısız
29
+ Failures: Başarısızlıklar
30
+ Failure: Başarısızlık
31
+ GoBack: ← Geri Dön
32
+ History: Geçmiş
33
+ Job: İş
34
+ Jobs: İşler
35
+ Kill: Sonlandır
36
+ KillAll: Hepsini Sonlandır
37
+ LastRetry: Son Yeniden Deneme
38
+ Latency: Gecikme
39
+ LivePoll: Canlı Anket
40
+ MemoryUsage: Bellek Kullanımı
41
+ Name: İsim
42
+ Namespace: Ad Alanı
43
+ NextRetry: Bir Sonraki Yeniden Deneme
44
+ NoDeadJobsFound: Ölü iş bulunamadı
45
+ NoRetriesFound: Yeniden deneme bulunamadı
46
+ NoScheduledFound: Zamanlanmış iş bulunamadı
47
+ NotYetEnqueued: Henüz kuyruğa alınmadı
48
+ OneMonth: 1 ay
49
+ OneWeek: 1 hafta
50
+ OriginallyFailed: İlk Başarısızlık
51
+ Pause: Duraklat
52
+ Paused: Duraklatıldı
53
+ PeakMemoryUsage: Maksimum Bellek Kullanımı
54
+ Plugins: Eklentiler
55
+ PollingInterval: Anket Aralığı
56
+ Process: Süreç
57
+ Processed: İşlendi
58
+ Processes: Süreçler
59
+ Queue: Kuyruk
60
+ Queues: Kuyruklar
61
+ Quiet: Sessiz
62
+ QuietAll: Hepsini Sessiz Yap
63
+ Realtime: Gerçek Zamanlı
64
+ Retries: Yeniden Denemeler
65
+ RetryAll: Hepsini Yeniden Dene
66
+ RetryCount: Yeniden Deneme Sayısı
67
+ RetryNow: Şimdi Yeniden Dene
68
+ Scheduled: Zamanlanmış
69
+ ScheduledJobs: Zamanlanmış İşler
70
+ Seconds: Saniye
71
+ ShowAll: Hepsini Göster
72
+ SixMonths: 6 ay
73
+ Size: Boyut
74
+ Started: Başlatıldı
75
+ Status: Durum
76
+ Stop: Durdur
77
+ StopAll: Hepsini Durdur
78
+ StopPolling: Anketi Durdur
79
+ Success: Başarı
80
+ Summary: Özet
81
+ Thread: İplik
82
+ Threads: İplikler
83
+ ThreeMonths: 3 ay
84
+ Time: Zaman
85
+ Unpause: Duraklatmayı Kaldır
86
+ Uptime: Çalışma Süresi (gün)
87
+ Utilization: Kullanım
88
+ Version: Sürüm
89
+ When: Ne Zaman
90
+ Worker: İşçi
91
+ active: aktif
92
+ idle: boşta
93
+ Metrics: Metrikler
94
+ NoDataFound: Veri bulunamadı
95
+ TotalExecutionTime: Toplam Yürütme Süresi
96
+ AvgExecutionTime: Ortalama Yürütme Süresi
97
+ Context: Bağlam
98
+ Bucket: Kova
99
+ NoJobMetricsFound: Son iş metrikleri bulunamadı
100
+ Filter: Filtre
101
+ AnyJobContent: Herhangi bir iş içeriği
@@ -1,4 +1,4 @@
1
- <script type="text/javascript" src="<%= root_path %>javascripts/dashboard.js"></script>
1
+ <script type="text/javascript" src="<%= root_path %>javascripts/dashboard.js" nonce="<%= csp_nonce %>"></script>
2
2
  <div class= "dashboard clearfix">
3
3
  <h3 >
4
4
  <%= t('Dashboard') %>
@@ -9,7 +9,7 @@
9
9
  </h3>
10
10
  <div class="interval-slider ltr">
11
11
  <span class="interval-slider-label"><%= t('PollingInterval') %>:</span>
12
- <span id="sldr-text" class="current-interval">5 sec</span>
12
+ <span id="sldr-text" class="current-interval">5 s</span>
13
13
  <br/>
14
14
  <input id="sldr" type="range" min="2000" max="20000" step="1000" value="5000"/>
15
15
  </div>
@@ -99,7 +99,7 @@
99
99
  </div>
100
100
  </div>
101
101
 
102
- <script type="text/javascript" src="<%= root_path %>javascripts/chart.min.js"></script>
103
- <script type="text/javascript" src="<%= root_path %>javascripts/chartjs-plugin-annotation.min.js"></script>
104
- <script type="text/javascript" src="<%= root_path %>javascripts/base-charts.js"></script>
105
- <script type="text/javascript" src="<%= root_path %>javascripts/dashboard-charts.js"></script>
102
+ <script type="text/javascript" src="<%= root_path %>javascripts/chart.min.js" nonce="<%= csp_nonce %>"></script>
103
+ <script type="text/javascript" src="<%= root_path %>javascripts/chartjs-plugin-annotation.min.js" nonce="<%= csp_nonce %>"></script>
104
+ <script type="text/javascript" src="<%= root_path %>javascripts/base-charts.js" nonce="<%= csp_nonce %>"></script>
105
+ <script type="text/javascript" src="<%= root_path %>javascripts/dashboard-charts.js" nonce="<%= csp_nonce %>"></script>
data/web/views/layout.erb CHANGED
@@ -5,20 +5,20 @@
5
5
  <meta charset="utf-8" />
6
6
  <meta name="viewport" content="width=device-width,initial-scale=1.0" />
7
7
 
8
- <link href="<%= root_path %>stylesheets/bootstrap.css" media="screen" rel="stylesheet" type="text/css" />
8
+ <link href="<%= root_path %>stylesheets/bootstrap.css" media="screen" rel="stylesheet" type="text/css" nonce="<%= csp_nonce %>" />
9
9
  <% if rtl? %>
10
- <link href="<%= root_path %>stylesheets/bootstrap-rtl.min.css" media="screen" rel="stylesheet" type="text/css"/>
10
+ <link href="<%= root_path %>stylesheets/bootstrap-rtl.min.css" media="screen" rel="stylesheet" type="text/css" nonce="<%= csp_nonce %>"/>
11
11
  <% end %>
12
12
 
13
- <link href="<%= root_path %>stylesheets/application.css" media="screen" rel="stylesheet" type="text/css" />
14
- <link href="<%= root_path %>stylesheets/application-dark.css" media="screen and (prefers-color-scheme: dark)" rel="stylesheet" type="text/css" />
13
+ <link href="<%= root_path %>stylesheets/application.css" media="screen" rel="stylesheet" type="text/css" nonce="<%= csp_nonce %>" />
14
+ <link href="<%= root_path %>stylesheets/application-dark.css" media="screen and (prefers-color-scheme: dark)" rel="stylesheet" type="text/css" nonce="<%= csp_nonce %>" />
15
15
  <% if rtl? %>
16
- <link href="<%= root_path %>stylesheets/application-rtl.css" media="screen" rel="stylesheet" type="text/css" />
16
+ <link href="<%= root_path %>stylesheets/application-rtl.css" media="screen" rel="stylesheet" type="text/css" nonce="<%= csp_nonce %>" />
17
17
  <% end %>
18
18
 
19
19
  <link rel="apple-touch-icon" href="<%= root_path %>images/apple-touch-icon.png">
20
20
  <link rel="shortcut icon" type="image/ico" href="<%= root_path %>images/favicon.ico" />
21
- <script type="text/javascript" src="<%= root_path %>javascripts/application.js"></script>
21
+ <script type="text/javascript" src="<%= root_path %>javascripts/application.js" nonce="<%= csp_nonce %>"></script>
22
22
  <meta name="google" content="notranslate" />
23
23
  <%= display_custom_head %>
24
24
  </head>
@@ -1,6 +1,6 @@
1
- <script type="text/javascript" src="<%= root_path %>javascripts/chart.min.js"></script>
2
- <script type="text/javascript" src="<%= root_path %>javascripts/chartjs-plugin-annotation.min.js"></script>
3
- <script type="text/javascript" src="<%= root_path %>javascripts/base-charts.js"></script>
1
+ <script type="text/javascript" src="<%= root_path %>javascripts/chart.min.js" nonce="<%= csp_nonce %>"></script>
2
+ <script type="text/javascript" src="<%= root_path %>javascripts/chartjs-plugin-annotation.min.js" nonce="<%= csp_nonce %>"></script>
3
+ <script type="text/javascript" src="<%= root_path %>javascripts/base-charts.js" nonce="<%= csp_nonce %>"></script>
4
4
 
5
5
  <div class="header-container">
6
6
  <div class="page-title-container">
@@ -88,4 +88,4 @@
88
88
 
89
89
  <!--p><small>Data from <%= @query_result.starts_at %> to <%= @query_result.ends_at %></small></p-->
90
90
 
91
- <script type="text/javascript" src="<%= root_path %>javascripts/metrics.js"></script>
91
+ <script type="text/javascript" src="<%= root_path %>javascripts/metrics.js" nonce="<%= csp_nonce %>"></script>
@@ -1,6 +1,6 @@
1
- <script type="text/javascript" src="<%= root_path %>javascripts/chart.min.js"></script>
2
- <script type="text/javascript" src="<%= root_path %>javascripts/chartjs-plugin-annotation.min.js"></script>
3
- <script type="text/javascript" src="<%= root_path %>javascripts/base-charts.js"></script>
1
+ <script type="text/javascript" src="<%= root_path %>javascripts/chart.min.js" nonce="<%= csp_nonce %>"></script>
2
+ <script type="text/javascript" src="<%= root_path %>javascripts/chartjs-plugin-annotation.min.js" nonce="<%= csp_nonce %>"></script>
3
+ <script type="text/javascript" src="<%= root_path %>javascripts/base-charts.js" nonce="<%= csp_nonce %>"></script>
4
4
 
5
5
  <%
6
6
  job_result = @query_result.job_results[@name]
@@ -56,4 +56,4 @@
56
56
  <div class="alert alert-success"><%= t('NoJobMetricsFound') %></div>
57
57
  <% end %>
58
58
 
59
- <script type="text/javascript" src="<%= root_path %>javascripts/metrics.js"></script>
59
+ <script type="text/javascript" src="<%= root_path %>javascripts/metrics.js" nonce="<%= csp_nonce %>"></script>
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: 7.2.4
4
+ version: 7.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Perham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-26 00:00:00.000000000 Z
11
+ date: 2024-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis-client
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.19.0
19
+ version: 0.22.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.19.0
26
+ version: 0.22.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: connection_pool
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "<"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: logger
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  description: Simple, efficient background processing for Ruby.
70
84
  email:
71
85
  - info@contribsys.com
@@ -96,7 +110,13 @@ files:
96
110
  - lib/sidekiq/deploy.rb
97
111
  - lib/sidekiq/embedded.rb
98
112
  - lib/sidekiq/fetch.rb
113
+ - lib/sidekiq/iterable_job.rb
99
114
  - lib/sidekiq/job.rb
115
+ - lib/sidekiq/job/interrupt_handler.rb
116
+ - lib/sidekiq/job/iterable.rb
117
+ - lib/sidekiq/job/iterable/active_record_enumerator.rb
118
+ - lib/sidekiq/job/iterable/csv_enumerator.rb
119
+ - lib/sidekiq/job/iterable/enumerators.rb
100
120
  - lib/sidekiq/job_logger.rb
101
121
  - lib/sidekiq/job_retry.rb
102
122
  - lib/sidekiq/job_util.rb
@@ -172,6 +192,7 @@ files:
172
192
  - web/locales/ru.yml
173
193
  - web/locales/sv.yml
174
194
  - web/locales/ta.yml
195
+ - web/locales/tr.yml
175
196
  - web/locales/uk.yml
176
197
  - web/locales/ur.yml
177
198
  - web/locales/vi.yml
@@ -224,7 +245,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
224
245
  - !ruby/object:Gem::Version
225
246
  version: '0'
226
247
  requirements: []
227
- rubygems_version: 3.4.20
248
+ rubygems_version: 3.5.11
228
249
  signing_key:
229
250
  specification_version: 4
230
251
  summary: Simple, efficient background processing for Ruby