sidekiq 7.2.4 → 7.3.1

Sign up to get free protection for your applications and to get access to all the features.
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