sidekiq 7.0.3 → 7.0.4

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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 93289a9aed52b658b609cb6de99fefe182003d71bcc0102fa82fa33d53a70f5b
4
- data.tar.gz: 1ca1b7ff222845a4a6f23ea00d77826c248a8e45db176eb9f2194afef70dface
3
+ metadata.gz: e461cc2bc3884aff75bfd57ffb8039f8695e364d34f84e8522cd2fb3ffb8266e
4
+ data.tar.gz: bd752a0cc1d6a5be73e51cca34636413db291f92de0bc0723e3cb95b7a34f9dc
5
5
  SHA512:
6
- metadata.gz: 680961f7df970445211487780291ecc1adb738fa834126428bbb814b0b7b03e912889c66020079f24aaf548a023c9621e601631d66dd6f7f467e9f8ac5085fee
7
- data.tar.gz: cdd1e337afbba5aaea110227e8b91e1b965e05c6ff9a5b7f5202850e3725d4d6959137dd8f47075057230451e394dca3ca0cbe5c7d70ef33ac6284a21e7fbea4
6
+ metadata.gz: d71996bea6ee081ab98bf626e0aa3bf3722e4ff1683b982bab4fd43abf371145573f7cd09392688f1db6739c57d3ceaf04834a605264db8c02747bd3eb623350
7
+ data.tar.gz: 81a1727add73469a9c2ea14b868e08f99c4b50b3cbc31f6277b312c055d207e285cc8b0ef749bb39b65ba832863b9ef05e7427147642bd7b9795344511b274d7
data/Changes.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # Sidekiq Changes
2
2
 
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)
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
+
5
+ HEAD
6
+ ----------
7
+
8
+ - Performance and memory optimizations [#5768, fatkodima]
9
+ - Add 1-8 hour period selector to Metrics pages [#5694]
10
+ - Fix process display with `sidekiqmon` [#5733]
4
11
 
5
12
  7.0.3
6
13
  ----------
@@ -88,7 +95,7 @@ end
88
95
  6.5.2
89
96
  ----------
90
97
 
91
- - [Job Metrics are under active development, help wanted!](https://github.com/mperham/sidekiq/wiki/Metrics#contributing) **BETA**
98
+ - [Job Metrics are under active development, help wanted!](https://github.com/sidekiq/sidekiq/wiki/Metrics#contributing) **BETA**
92
99
  - Add `Context` column on queue page which shows any CurrentAttributes [#5450]
93
100
  - `sidekiq_retry_in` may now return `:discard` or `:kill` to dynamically stop job retries [#5406]
94
101
  - Smarter sorting of processes in /busy Web UI [#5398]
@@ -107,7 +114,7 @@ end
107
114
  - Substantial refactoring of Sidekiq server internals, part of a larger effort
108
115
  to reduce Sidekiq's internal usage of global methods and data, see [docs/global_to_local.md](docs/global_to_local.md) and [docs/middleware.md](docs/middleware.md).
109
116
  - **Add beta support for the `redis-client` gem**. This will become the default Redis driver in Sidekiq 7.0. [#5298]
110
- Read more: https://github.com/mperham/sidekiq/wiki/Using-redis-client
117
+ Read more: https://github.com/sidekiq/sidekiq/wiki/Using-redis-client
111
118
  - **Add beta support for DB transaction-aware client** [#5291]
112
119
  Add this line to your initializer and any jobs created during a transaction
113
120
  will only be pushed to Redis **after the transaction commits**. You will need to add the
@@ -307,7 +314,7 @@ If this is a Rails app in API mode, you need to enable sessions.
307
314
  ---------
308
315
 
309
316
  - **Integrate with systemd's watchdog and notification features** [#4488]
310
- Set `Type=notify` in [sidekiq.service](https://github.com/mperham/sidekiq/blob/4b8a8bd3ae42f6e48ae1fdaf95ed7d7af18ed8bb/examples/systemd/sidekiq.service#L30-L39). The integration works automatically.
317
+ Set `Type=notify` in [sidekiq.service](https://github.com/sidekiq/sidekiq/blob/4b8a8bd3ae42f6e48ae1fdaf95ed7d7af18ed8bb/examples/systemd/sidekiq.service#L30-L39). The integration works automatically.
311
318
  - Use `setTimeout` rather than `setInterval` to avoid thundering herd [#4480]
312
319
  - Fix edge case where a job can be pushed without a queue.
313
320
  - Flush job stats at exit [#4498]
@@ -320,7 +327,7 @@ If this is a Rails app in API mode, you need to enable sessions.
320
327
  - Fix broken Web UI response when using NewRelic and Rack 2.1.2+. [#4440]
321
328
  - Update APIs to use `UNLINK`, not `DEL`. [#4449]
322
329
  - Fix Ruby 2.7 warnings [#4412]
323
- - Add support for `APP_ENV` [[95fa5d9]](https://github.com/mperham/sidekiq/commit/95fa5d90192148026e52ca2902f1b83c70858ce8)
330
+ - Add support for `APP_ENV` [[95fa5d9]](https://github.com/sidekiq/sidekiq/commit/95fa5d90192148026e52ca2902f1b83c70858ce8)
324
331
 
325
332
  6.0.4
326
333
  ---------
@@ -432,7 +439,7 @@ Sidekiq.configure_server do |config|
432
439
  config.log_formatter = Sidekiq::Logger::Formatters::JSON.new
433
440
  end
434
441
  ```
435
- See the [Logging wiki page](https://github.com/mperham/sidekiq/wiki/Logging) for more details.
442
+ See the [Logging wiki page](https://github.com/sidekiq/sidekiq/wiki/Logging) for more details.
436
443
  - **BREAKING CHANGE** Validate proper usage of the `REDIS_PROVIDER`
437
444
  variable. This variable is meant to hold the name of the environment
438
445
  variable which contains your Redis URL, so that you can switch Redis
@@ -879,7 +886,7 @@ Sidekiq::Queues.clear_all
879
886
  - **FIX MEMORY LEAK** Under rare conditions, threads may leak [#2598, gazay]
880
887
  - Add Ukrainian locale [#2561, elrakita]
881
888
  - Disconnect and retry Redis operations if we see a READONLY error [#2550]
882
- - Add server middleware testing harness; see [wiki](https://github.com/mperham/sidekiq/wiki/Testing#testing-server-middleware) [#2534, ryansch]
889
+ - Add server middleware testing harness; see [wiki](https://github.com/sidekiq/sidekiq/wiki/Testing#testing-server-middleware) [#2534, ryansch]
883
890
 
884
891
  3.5.0
885
892
  -----------
@@ -897,7 +904,7 @@ Sidekiq::Queues.clear_all
897
904
  - Fix CSRF vulnerability in Web UI, thanks to Egor Homakov for
898
905
  reporting. [#2422] If you are running the Web UI as a standalone Rack app,
899
906
  ensure you have a [session middleware
900
- configured](https://github.com/mperham/sidekiq/wiki/Monitoring#standalone):
907
+ configured](https://github.com/sidekiq/sidekiq/wiki/Monitoring#standalone):
901
908
  ```ruby
902
909
  use Rack::Session::Cookie, :secret => "some unique secret string here"
903
910
  ```
@@ -1281,7 +1288,7 @@ middleware, see docs/3.0-Upgrade.md.**
1281
1288
  appear to be doing any work. [#1194]
1282
1289
  - Sidekiq's testing behavior is now dynamic. You can choose between
1283
1290
  `inline` and `fake` behavior in your tests. See
1284
- [Testing](https://github.com/mperham/sidekiq/wiki/Testing) for detail. [#1193]
1291
+ [Testing](https://github.com/sidekiq/sidekiq/wiki/Testing) for detail. [#1193]
1285
1292
  - The Retries table has a new column for the error message.
1286
1293
  - The Web UI topbar now contains the status and live poll button.
1287
1294
  - Orphaned worker records are now auto-vacuumed when you visit the
data/README.md CHANGED
@@ -2,7 +2,7 @@ Sidekiq
2
2
  ==============
3
3
 
4
4
  [![Gem Version](https://badge.fury.io/rb/sidekiq.svg)](https://rubygems.org/gems/sidekiq)
5
- ![Build](https://github.com/mperham/sidekiq/workflows/CI/badge.svg)
5
+ ![Build](https://github.com/sidekiq/sidekiq/workflows/CI/badge.svg)
6
6
 
7
7
  Simple, efficient background processing for Ruby.
8
8
 
@@ -10,19 +10,6 @@ Sidekiq uses threads to handle many jobs at the same time in the
10
10
  same process. It does not require Rails but will integrate tightly with
11
11
  Rails to make background processing dead simple.
12
12
 
13
- Performance
14
- ---------------
15
-
16
- Version | Latency | Garbage created for 10k jobs | Time to process 100k jobs | Throughput | Ruby
17
- -----------------|------|---------|---------|------------------------|-----
18
- Sidekiq 6.0.2 | 3 ms | 156 MB | 14.0 sec| **7100 jobs/sec** | MRI 2.6.3
19
- Sidekiq 6.0.0 | 3 ms | 156 MB | 19 sec | 5200 jobs/sec | MRI 2.6.3
20
- Sidekiq 4.0.0 | 10 ms | 151 MB | 22 sec | 4500 jobs/sec |
21
- Sidekiq 3.5.1 | 22 ms | 1257 MB | 125 sec | 800 jobs/sec |
22
- Resque 1.25.2 | - | - | 420 sec | 240 jobs/sec |
23
- DelayedJob 4.1.1 | - | - | 465 sec | 215 jobs/sec |
24
-
25
- This benchmark can be found in `bin/sidekiqload` and assumes a Redis network latency of 1ms.
26
13
 
27
14
  Requirements
28
15
  -----------------
@@ -42,12 +29,32 @@ Installation
42
29
  Getting Started
43
30
  -----------------
44
31
 
45
- See the [Getting Started wiki page](https://github.com/mperham/sidekiq/wiki/Getting-Started) and follow the simple setup process.
32
+ See the [Getting Started wiki page](https://github.com/sidekiq/sidekiq/wiki/Getting-Started) and follow the simple setup process.
46
33
  You can watch [this YouTube playlist](https://www.youtube.com/playlist?list=PLjeHh2LSCFrWGT5uVjUuFKAcrcj5kSai1) to learn all about
47
34
  Sidekiq and see its features in action. Here's the Web UI:
48
35
 
49
- ![Web UI](https://github.com/mperham/sidekiq/raw/main/examples/web-ui.png)
36
+ ![Web UI](https://github.com/sidekiq/sidekiq/raw/main/examples/web-ui.png)
37
+
38
+ Performance
39
+ ---------------
40
+
41
+ The benchmark in `bin/sidekiqload` creates 500,000 no-op jobs and drains them as fast as possible, assuming a fixed Redis network latency of 1ms.
42
+ This requires a lot of Redis network I/O and JSON parsing.
43
+ This benchmark is IO-bound so we increase the concurrency to 25.
44
+ If your application is sending lots of emails or performing other network-intensive work, you could see a similar benefit but be careful not to saturate the CPU.
45
+
46
+ Version | Time to process 500k jobs | Throughput (jobs/sec) | Ruby | Concurrency | Job Type
47
+ -----------------|------|---------|---------|------------------------|---
48
+ Sidekiq 7.0.3 | 21.3 sec| 23,500 | 3.2.0+yjit | 30 | Sidekiq::Job
49
+ Sidekiq 7.0.3 | 33.8 sec| 14,700 | 3.2.0+yjit | 30 | ActiveJob 7.0.4
50
+ Sidekiq 7.0.3 | 23.5 sec| 21,300 | 3.2.0 | 30 | Sidekiq::Job
51
+ Sidekiq 7.0.3 | 46.5 sec| 10,700 | 3.2.0 | 30 | ActiveJob 7.0.4
52
+ Sidekiq 7.0.3 | 23.0 sec| 21,700 | 2.7.5 | 30 | Sidekiq::Job
53
+ Sidekiq 7.0.3 | 46.5 sec| 10,850 | 2.7.5 | 30 | ActiveJob 7.0.4
50
54
 
55
+ Most of Sidekiq's overhead is Redis network I/O.
56
+ ActiveJob adds a notable amount of CPU overhead due to argument deserialization and callbacks.
57
+ Concurrency of 30 was determined experimentally to maximize one CPU without saturating it.
51
58
 
52
59
  Want to Upgrade?
53
60
  -------------------
@@ -67,15 +74,15 @@ Problems?
67
74
  **Please do not directly email any Sidekiq committers with questions or problems.**
68
75
  A community is best served when discussions are held in public.
69
76
 
70
- If you have a problem, please review the [FAQ](https://github.com/mperham/sidekiq/wiki/FAQ) and [Troubleshooting](https://github.com/mperham/sidekiq/wiki/Problems-and-Troubleshooting) wiki pages.
71
- Searching the [issues](https://github.com/mperham/sidekiq/issues) for your problem is also a good idea.
77
+ If you have a problem, please review the [FAQ](https://github.com/sidekiq/sidekiq/wiki/FAQ) and [Troubleshooting](https://github.com/sidekiq/sidekiq/wiki/Problems-and-Troubleshooting) wiki pages.
78
+ Searching the [issues](https://github.com/sidekiq/sidekiq/issues) for your problem is also a good idea.
72
79
 
73
80
  Sidekiq Pro and Sidekiq Enterprise customers get private email support.
74
81
  You can purchase at https://sidekiq.org; email support@contribsys.com for help.
75
82
 
76
83
  Useful resources:
77
84
 
78
- * Product documentation is in the [wiki](https://github.com/mperham/sidekiq/wiki).
85
+ * Product documentation is in the [wiki](https://github.com/sidekiq/sidekiq/wiki).
79
86
  * Occasional announcements are made to the [@sidekiq](https://twitter.com/sidekiq) Twitter account.
80
87
  * The [Sidekiq tag](https://stackoverflow.com/questions/tagged/sidekiq) on Stack Overflow has lots of useful Q & A.
81
88
 
@@ -85,13 +92,13 @@ See the [Sidekiq support page](https://sidekiq.org/support.html) for details.
85
92
  Contributing
86
93
  -----------------
87
94
 
88
- Please see [the contributing guidelines](https://github.com/mperham/sidekiq/blob/main/.github/contributing.md).
95
+ Please see [the contributing guidelines](https://github.com/sidekiq/sidekiq/blob/main/.github/contributing.md).
89
96
 
90
97
  License
91
98
  -----------------
92
99
 
93
- Please see [LICENSE.txt](https://github.com/mperham/sidekiq/blob/main/LICENSE.txt) for licensing details.
94
- The license for Sidekiq Pro and Sidekiq Enterprise can be found in [COMM-LICENSE.txt](https://github.com/mperham/sidekiq/blob/main/COMM-LICENSE.txt).
100
+ Please see [LICENSE.txt](https://github.com/sidekiq/sidekiq/blob/main/LICENSE.txt) for licensing details.
101
+ The license for Sidekiq Pro and Sidekiq Enterprise can be found in [COMM-LICENSE.txt](https://github.com/sidekiq/sidekiq/blob/main/COMM-LICENSE.txt).
95
102
 
96
103
  Author
97
104
  -----------------
data/bin/sidekiqload CHANGED
@@ -3,19 +3,39 @@
3
3
  # Quiet some warnings we see when running in warning mode:
4
4
  # RUBYOPT=-w bundle exec sidekiq
5
5
  $TESTING = false
6
+ puts RUBY_DESCRIPTION
7
+ puts(%w[THREADS LATENCY AJ PROFILE].map { |x| "#{x}: #{ENV[x] || "nil"}" }.join(", "))
6
8
 
7
- # require "ruby-prof"
9
+ require "ruby-prof" if ENV["PROFILE"]
8
10
  require "bundler/setup"
9
11
  Bundler.require(:default, :load_test)
10
12
 
11
- x = Sidekiq.configure_embed do |config|
12
- config.redis = {db: 13, port: 6380}
13
- config.concurrency = 10
14
- # config.redis = { db: 13, port: 6380, driver: :hiredis}
15
- config.queues = %w[default]
16
- config.logger.level = Logger::ERROR
17
- config.average_scheduled_poll_interval = 2
18
- config.reliable! if defined?(Sidekiq::Pro)
13
+ latency = Integer(ENV["LATENCY"] || 1)
14
+ if latency > 0
15
+ # brew tap shopify/shopify
16
+ # brew install toxiproxy
17
+ # run `toxiproxy-server` in a separate terminal window.
18
+ require "toxiproxy"
19
+ # simulate a non-localhost network for realer-world conditions.
20
+ # adding 1ms of network latency has an ENORMOUS impact on benchmarks
21
+ Toxiproxy.populate([{
22
+ name: "redis",
23
+ listen: "127.0.0.1:6380",
24
+ upstream: "127.0.0.1:6379"
25
+ }])
26
+ end
27
+
28
+ if ENV["AJ"]
29
+ require "active_job"
30
+ puts "Using ActiveJob #{ActiveJob::VERSION::STRING}"
31
+ ActiveJob::Base.queue_adapter = :sidekiq
32
+ ActiveJob::Base.logger.level = Logger::WARN
33
+
34
+ class LoadJob < ActiveJob::Base
35
+ def perform(idx, ts=nil)
36
+ puts(Time.now.to_f - ts) if !ts.nil?
37
+ end
38
+ end
19
39
  end
20
40
 
21
41
  class LoadWorker
@@ -31,122 +51,179 @@ class LoadWorker
31
51
  end
32
52
  end
33
53
 
34
- # brew tap shopify/shopify
35
- # brew install toxiproxy
36
- # run `toxiproxy-server` in a separate terminal window.
37
- require "toxiproxy"
38
- # simulate a non-localhost network for realer-world conditions.
39
- # adding 1ms of network latency has an ENORMOUS impact on benchmarks
40
- Toxiproxy.populate([{
41
- name: "redis",
42
- listen: "127.0.0.1:6380",
43
- upstream: "127.0.0.1:6379"
44
- }])
45
-
46
- self_read, self_write = IO.pipe
47
- %w[INT TERM TSTP TTIN].each do |sig|
48
- trap sig do
49
- self_write.puts(sig)
50
- end
51
- rescue ArgumentError
52
- puts "Signal #{sig} not supported"
54
+ def Process.rss
55
+ `ps -o rss= -p #{Process.pid}`.chomp.to_i
53
56
  end
54
57
 
55
- Sidekiq.redis { |c| c.flushdb }
56
- def handle_signal(launcher, sig)
57
- Sidekiq.logger.debug "Got #{sig} signal"
58
- case sig
59
- when "INT"
60
- # Handle Ctrl-C in JRuby like MRI
61
- # http://jira.codehaus.org/browse/JRUBY-4637
62
- raise Interrupt
63
- when "TERM"
64
- # Heroku sends TERM and then waits 30 seconds for process to exit.
65
- raise Interrupt
66
- when "TSTP"
67
- Sidekiq.logger.info "Received TSTP, no longer accepting new work"
68
- launcher.quiet
69
- when "TTIN"
70
- Thread.list.each do |thread|
71
- Sidekiq.logger.warn "Thread TID-#{(thread.object_id ^ ::Process.pid).to_s(36)} #{thread["label"]}"
72
- if thread.backtrace
73
- Sidekiq.logger.warn thread.backtrace.join("\n")
74
- else
75
- Sidekiq.logger.warn "<no backtrace available>"
58
+ class Loader
59
+ def initialize
60
+ @iter = ENV["GC"] ? 10 : 500
61
+ @count = Integer(ENV["COUNT"] || 1_000)
62
+ @latency = Integer(ENV["LATENCY"] || 1)
63
+ end
64
+
65
+ def configure
66
+ @x = Sidekiq.configure_embed do |config|
67
+ config.redis = {db: 13, port: ((@latency > 0) ? 6380 : 6379)}
68
+ config.concurrency = Integer(ENV.fetch("THREADS", "10"))
69
+ # config.redis = { db: 13, port: 6380, driver: :hiredis}
70
+ config.queues = %w[default]
71
+ config.logger.level = Logger::WARN
72
+ config.average_scheduled_poll_interval = 2
73
+ config.reliable! if defined?(Sidekiq::Pro)
74
+ end
75
+
76
+ @self_read, @self_write = IO.pipe
77
+ %w[INT TERM TSTP TTIN].each do |sig|
78
+ trap sig do
79
+ @self_write.puts(sig)
76
80
  end
81
+ rescue ArgumentError
82
+ puts "Signal #{sig} not supported"
77
83
  end
78
84
  end
79
- end
80
85
 
81
- def Process.rss
82
- `ps -o rss= -p #{Process.pid}`.chomp.to_i
83
- end
86
+ def handle_signal(sig)
87
+ launcher = @x
88
+ Sidekiq.logger.debug "Got #{sig} signal"
89
+ case sig
90
+ when "INT"
91
+ # Handle Ctrl-C in JRuby like MRI
92
+ # http://jira.codehaus.org/browse/JRUBY-4637
93
+ raise Interrupt
94
+ when "TERM"
95
+ # Heroku sends TERM and then waits 30 seconds for process to exit.
96
+ raise Interrupt
97
+ when "TSTP"
98
+ Sidekiq.logger.info "Received TSTP, no longer accepting new work"
99
+ launcher.quiet
100
+ when "TTIN"
101
+ Thread.list.each do |thread|
102
+ Sidekiq.logger.warn "Thread TID-#{(thread.object_id ^ ::Process.pid).to_s(36)} #{thread["label"]}"
103
+ if thread.backtrace
104
+ Sidekiq.logger.warn thread.backtrace.join("\n")
105
+ else
106
+ Sidekiq.logger.warn "<no backtrace available>"
107
+ end
108
+ end
109
+ end
110
+ end
84
111
 
85
- iter = 10
86
- count = 10_000
112
+ def setup
113
+ Sidekiq.logger.error("Setup RSS: #{Process.rss}")
114
+ Sidekiq.redis { |c| c.flushdb }
115
+ start = Time.now
116
+ if ENV["AJ"]
117
+ @iter.times do
118
+ @count.times do |idx|
119
+ LoadJob.perform_later(idx)
120
+ end
121
+ end
122
+ else
123
+ @iter.times do
124
+ arr = Array.new(@count) { |idx| [idx] }
125
+ Sidekiq::Client.push_bulk("class" => LoadWorker, "args" => arr)
126
+ end
127
+ end
128
+ Sidekiq.logger.warn "Created #{@count * @iter} jobs in #{Time.now - start} sec"
129
+ end
87
130
 
88
- iter.times do
89
- arr = Array.new(count) { |idx| [idx] }
90
- Sidekiq::Client.push_bulk("class" => LoadWorker, "args" => arr)
91
- end
92
- Sidekiq.logger.error "Created #{count * iter} jobs"
131
+ def monitor
132
+ @monitor = Thread.new do
133
+ GC.start
134
+ loop do
135
+ sleep 0.2
136
+ qsize = Sidekiq.redis do |conn|
137
+ conn.llen "queue:default"
138
+ end
139
+ total = qsize
140
+ if total == 0
141
+ ending = Time.now - @start
142
+ size = @iter * @count
143
+ Sidekiq.logger.error("Done, #{size} jobs in #{ending} sec, #{(size / ending).to_i} jobs/sec")
144
+ Sidekiq.logger.error("Ending RSS: #{Process.rss}")
145
+ Sidekiq.logger.error("Now here's the latency for three jobs")
146
+
147
+ if ENV["AJ"]
148
+ LoadJob.perform_later(1, Time.now.to_f)
149
+ LoadJob.perform_later(2, Time.now.to_f)
150
+ LoadJob.perform_later(3, Time.now.to_f)
151
+ else
152
+ LoadWorker.perform_async(1, Time.now.to_f)
153
+ LoadWorker.perform_async(2, Time.now.to_f)
154
+ LoadWorker.perform_async(3, Time.now.to_f)
155
+ end
156
+
157
+ sleep 0.1
158
+ @x.stop
159
+ Process.kill("INT", $$)
160
+ break
161
+ end
162
+ end
163
+ end
164
+ end
93
165
 
94
- start = Time.now
166
+ def with_latency(latency, &block)
167
+ Sidekiq.logger.error "Simulating #{latency}ms of latency between Sidekiq and redis"
168
+ if latency > 0
169
+ Toxiproxy[:redis].downstream(:latency, latency: latency).apply(&block)
170
+ else
171
+ yield
172
+ end
173
+ end
95
174
 
96
- Monitoring = Thread.new do
97
- loop do
98
- sleep 1.0
99
- qsize = Sidekiq.redis do |conn|
100
- conn.llen "queue:default"
175
+ def run(name)
176
+ Sidekiq.logger.warn("Starting #{name}")
177
+ monitor
178
+
179
+ if ENV["PROFILE"]
180
+ RubyProf.exclude_threads = [@monitor]
181
+ RubyProf.start
182
+ elsif ENV["GC"]
183
+ GC.start
184
+ GC.compact
185
+ GC.disable
186
+ Sidekiq.logger.error("GC Start RSS: #{Process.rss}")
101
187
  end
102
- total = qsize
103
- # Sidekiq.logger.error("RSS: #{Process.rss} Pending: #{total}")
104
- if total == 0
105
- Sidekiq.logger.error("Done, #{iter * count} jobs in #{Time.now - start} sec")
106
- Sidekiq.logger.error("Now here's the latency for three jobs")
107
-
108
- LoadWorker.perform_async(1, Time.now.to_f)
109
- LoadWorker.perform_async(2, Time.now.to_f)
110
- LoadWorker.perform_async(3, Time.now.to_f)
111
-
112
- sleep 0.2
113
- exit(0)
188
+ @start = Time.now
189
+ with_latency(@latency) do
190
+ @x.run
191
+
192
+ while (readable_io = IO.select([@self_read]))
193
+ signal = readable_io.first[0].gets.strip
194
+ handle_signal(signal)
195
+ end
114
196
  end
197
+ # normal
198
+ rescue Interrupt
199
+ rescue => e
200
+ raise e if $DEBUG
201
+ warn e.message
202
+ warn e.backtrace.join("\n")
203
+ exit 1
204
+ ensure
205
+ @x.stop
115
206
  end
116
- end
117
207
 
118
- def with_latency(latency, &block)
119
- Sidekiq.logger.error "Simulating #{latency}ms of latency between Sidekiq and redis"
120
- if latency > 0
121
- Toxiproxy[:redis].downstream(:latency, latency: latency).apply(&block)
122
- else
123
- yield
208
+ def done
209
+ Sidekiq.logger.error("GC End RSS: #{Process.rss}") if ENV["GC"]
210
+ if ENV["PROFILE"]
211
+ Sidekiq.logger.error("Profiling...")
212
+ result = RubyProf.stop
213
+ printer = RubyProf::GraphHtmlPrinter.new(result)
214
+ printer.print(File.new("output.html", "w"), min_percent: 1)
215
+ end
124
216
  end
125
217
  end
126
218
 
127
- begin
128
- # RubyProf.exclude_threads = [Monitoring]
129
- # RubyProf.start
219
+ ll = Loader.new
220
+ ll.configure
130
221
 
131
- with_latency(Integer(ENV.fetch("LATENCY", "1"))) do
132
- x.run
133
-
134
- while (readable_io = IO.select([self_read]))
135
- signal = readable_io.first[0].gets.strip
136
- handle_signal(x, signal)
137
- end
138
- end
139
- rescue SystemExit
140
- # Sidekiq.logger.error("Profiling...")
141
- # result = RubyProf.stop
142
- # printer = RubyProf::GraphHtmlPrinter.new(result)
143
- # printer.print(File.new("output.html", "w"), min_percent: 1)
144
- # normal
145
- rescue => e
146
- raise e if $DEBUG
147
- warn e.message
148
- warn e.backtrace.join("\n")
149
- exit 1
150
- ensure
151
- x.stop
222
+ unless ENV["GC"] || ENV["PROFILE"]
223
+ ll.setup
224
+ ll.run("warmup")
152
225
  end
226
+
227
+ ll.setup
228
+ ll.run("ideal")
229
+ ll.done
data/bin/sidekiqmon CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  require "sidekiq/monitor"
4
4
 
5
+ # disable the Redis connection pool logging
6
+ Sidekiq.default_configuration.logger.level = :warn
7
+
5
8
  section = "all"
6
9
  section = ARGV[0] if ARGV.size == 1
7
10
 
data/lib/sidekiq/api.rb CHANGED
@@ -702,7 +702,7 @@ module Sidekiq
702
702
  def find_job(jid)
703
703
  Sidekiq.redis do |conn|
704
704
  conn.zscan(name, match: "*#{jid}*", count: 100) do |entry, score|
705
- job = JSON.parse(entry)
705
+ job = Sidekiq.load_json(entry)
706
706
  matched = job["jid"] == jid
707
707
  return SortedEntry.new(self, score, entry) if matched
708
708
  end
@@ -28,6 +28,7 @@ module Sidekiq
28
28
  @name = name
29
29
  @config = config
30
30
  @queues = ["default"]
31
+ @weights = {"default" => 0}
31
32
  @concurrency = config[:concurrency]
32
33
  @mode = :strict
33
34
  end
data/lib/sidekiq/cli.rb CHANGED
@@ -84,7 +84,7 @@ module Sidekiq # :nodoc:
84
84
 
85
85
  WARNING: Your Redis instance will evict Sidekiq data under heavy load.
86
86
  The 'noeviction' maxmemory policy is recommended (current policy: '#{maxmemory_policy}').
87
- See: https://github.com/mperham/sidekiq/wiki/Using-Redis#memory
87
+ See: https://github.com/sidekiq/sidekiq/wiki/Using-Redis#memory
88
88
 
89
89
  EOM
90
90
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Sidekiq
2
4
  ##
3
5
  # Sidekiq::Component assumes a config instance is available at @config
@@ -49,7 +49,7 @@ module Sidekiq
49
49
 
50
50
  WARNING: Your Redis instance will evict Sidekiq data under heavy load.
51
51
  The 'noeviction' maxmemory policy is recommended (current policy: '#{maxmemory_policy}').
52
- See: https://github.com/mperham/sidekiq/wiki/Using-Redis#memory
52
+ See: https://github.com/sidekiq/sidekiq/wiki/Using-Redis#memory
53
53
 
54
54
  EOM
55
55
  end
@@ -18,16 +18,17 @@ module Sidekiq
18
18
  def verify_json(item)
19
19
  job_class = item["wrapped"] || item["class"]
20
20
  if Sidekiq::Config::DEFAULTS[:on_complex_arguments] == :raise
21
- msg = <<~EOM
22
- Job arguments to #{job_class} must be native JSON types, see https://github.com/mperham/sidekiq/wiki/Best-Practices.
23
- To disable this error, add `Sidekiq.strict_args!(false)` to your initializer.
24
- EOM
25
- raise(ArgumentError, msg) unless json_safe?(item)
21
+ unless json_safe?(item["args"])
22
+ msg = <<~EOM
23
+ Job arguments to #{job_class} must be native JSON types, see https://github.com/sidekiq/sidekiq/wiki/Best-Practices.
24
+ To disable this error, add `Sidekiq.strict_args!(false)` to your initializer.
25
+ EOM
26
+ raise(ArgumentError, msg)
27
+ end
26
28
  elsif Sidekiq::Config::DEFAULTS[:on_complex_arguments] == :warn
27
- warn <<~EOM unless json_safe?(item)
28
- Job arguments to #{job_class} do not serialize to JSON safely. This will raise an error in
29
- Sidekiq 7.0. See https://github.com/mperham/sidekiq/wiki/Best-Practices or raise an error today
30
- by calling `Sidekiq.strict_args!` during Sidekiq initialization.
29
+ warn <<~EOM unless json_safe?(item["args"])
30
+ Job arguments to #{job_class} must be native JSON types, see https://github.com/sidekiq/sidekiq/wiki/Best-Practices.
31
+ To disable this warning, add `Sidekiq.strict_args!(false)` to your initializer.
31
32
  EOM
32
33
  end
33
34
  end
@@ -64,8 +65,27 @@ module Sidekiq
64
65
 
65
66
  private
66
67
 
68
+ RECURSIVE_JSON_SAFE = {
69
+ Integer => ->(val) { true },
70
+ Float => ->(val) { true },
71
+ TrueClass => ->(val) { true },
72
+ FalseClass => ->(val) { true },
73
+ NilClass => ->(val) { true },
74
+ String => ->(val) { true },
75
+ Array => ->(val) {
76
+ val.all? { |e| RECURSIVE_JSON_SAFE[e.class].call(e) }
77
+ },
78
+ Hash => ->(val) {
79
+ val.all? { |k, v| String === k && RECURSIVE_JSON_SAFE[v.class].call(v) }
80
+ }
81
+ }
82
+
83
+ RECURSIVE_JSON_SAFE.default = ->(_val) { false }
84
+ RECURSIVE_JSON_SAFE.compare_by_identity
85
+ private_constant :RECURSIVE_JSON_SAFE
86
+
67
87
  def json_safe?(item)
68
- JSON.parse(JSON.dump(item["args"])) == item["args"]
88
+ RECURSIVE_JSON_SAFE[item.class].call(item)
69
89
  end
70
90
  end
71
91
  end
@@ -214,7 +214,7 @@ module Sidekiq
214
214
  Last RTT readings were #{RTT_READINGS.buffer.inspect}, ideally these should be < 1000.
215
215
  Ensure Redis is running in the same AZ or datacenter as Sidekiq.
216
216
  If these values are close to 100,000, that means your Sidekiq process may be
217
- CPU-saturated; reduce your concurrency and/or see https://github.com/mperham/sidekiq/discussions/5039
217
+ CPU-saturated; reduce your concurrency and/or see https://github.com/sidekiq/sidekiq/discussions/5039
218
218
  EOM
219
219
  RTT_READINGS.reset
220
220
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "time"
2
4
  require "sidekiq"
3
5
  require "sidekiq/metrics/shared"
@@ -166,23 +166,26 @@ module Sidekiq
166
166
 
167
167
  # Used by Sidekiq to execute the middleware at runtime
168
168
  # @api private
169
- def invoke(*args)
169
+ def invoke(*args, &block)
170
170
  return yield if empty?
171
171
 
172
172
  chain = retrieve
173
- traverse_chain = proc do
174
- if chain.empty?
175
- yield
176
- else
177
- chain.shift.call(*args, &traverse_chain)
173
+ traverse(chain, 0, args, &block)
174
+ end
175
+
176
+ private
177
+
178
+ def traverse(chain, index, args, &block)
179
+ if index >= chain.size
180
+ yield
181
+ else
182
+ chain[index].call(*args) do
183
+ traverse(chain, index + 1, args, &block)
178
184
  end
179
185
  end
180
- traverse_chain.call
181
186
  end
182
187
  end
183
188
 
184
- private
185
-
186
189
  # Represents each link in the middleware chain
187
190
  # @api private
188
191
  class Entry
@@ -16,8 +16,6 @@ class Sidekiq::Monitor
16
16
  return
17
17
  end
18
18
  send(section)
19
- rescue => e
20
- abort "Couldn't get status: #{e}"
21
19
  end
22
20
 
23
21
  def all
@@ -58,7 +56,7 @@ class Sidekiq::Monitor
58
56
  # {"default" => 1, "critical" => 10}
59
57
  queues =
60
58
  if process["weights"]
61
- process["weights"].sort_by { |queue| queue[0] }.map { |queue| queue.join(": ") }
59
+ process["weights"].sort_by { |queue| queue[0] }.map { |capsule| capsule.map { |name, weight| (weight > 0) ? "#{name}: #{weight}" : name }.join(", ") }
62
60
  else
63
61
  process["queues"].sort
64
62
  end
@@ -146,6 +146,9 @@ module Sidekiq
146
146
  end
147
147
  end
148
148
 
149
+ IGNORE_SHUTDOWN_INTERRUPTS = {Sidekiq::Shutdown => :never}
150
+ private_constant :IGNORE_SHUTDOWN_INTERRUPTS
151
+
149
152
  def process(uow)
150
153
  jobstr = uow.job
151
154
  queue = uow.queue_name
@@ -195,7 +198,7 @@ module Sidekiq
195
198
  ensure
196
199
  if ack
197
200
  # We don't want a shutdown signal to interrupt job acknowledgment.
198
- Thread.handle_interrupt(Sidekiq::Shutdown => :never) do
201
+ Thread.handle_interrupt(IGNORE_SHUTDOWN_INTERRUPTS) do
199
202
  uow.acknowledge
200
203
  end
201
204
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sidekiq
4
- VERSION = "7.0.3"
4
+ VERSION = "7.0.4"
5
5
  MAJOR = 7
6
6
  end
@@ -20,6 +20,12 @@ module Sidekiq
20
20
  "worker-src 'self'",
21
21
  "base-uri 'self'"
22
22
  ].join("; ").freeze
23
+ METRICS_PERIODS = {
24
+ "1h" => 60,
25
+ "2h" => 120,
26
+ "4h" => 240,
27
+ "8h" => 480
28
+ }
23
29
 
24
30
  def initialize(klass)
25
31
  @klass = klass
@@ -62,14 +68,20 @@ module Sidekiq
62
68
 
63
69
  get "/metrics" do
64
70
  q = Sidekiq::Metrics::Query.new
65
- @query_result = q.top_jobs
71
+ @period = params[:period]
72
+ @periods = METRICS_PERIODS
73
+ minutes = @periods.fetch(@period, @periods.values.first)
74
+ @query_result = q.top_jobs(minutes: minutes)
66
75
  erb(:metrics)
67
76
  end
68
77
 
69
78
  get "/metrics/:name" do
70
79
  @name = route_params[:name]
80
+ @period = params[:period]
71
81
  q = Sidekiq::Metrics::Query.new
72
- @query_result = q.for_job(@name)
82
+ @periods = METRICS_PERIODS
83
+ minutes = @periods.fetch(@period, @periods.values.first)
84
+ @query_result = q.for_job(@name, minutes: minutes)
73
85
  erb(:metrics_for_job)
74
86
  end
75
87
 
@@ -15,7 +15,7 @@ module Sidekiq
15
15
  # so extensions can be localized
16
16
  @strings[lang] ||= settings.locales.each_with_object({}) do |path, global|
17
17
  find_locale_files(lang).each do |file|
18
- strs = YAML.safe_load(File.open(file))
18
+ strs = YAML.safe_load(File.read(file))
19
19
  global.merge!(strs[lang])
20
20
  end
21
21
  end
@@ -118,7 +118,7 @@ module Sidekiq
118
118
  }.join(" ")
119
119
  end
120
120
 
121
- # mperham/sidekiq#3243
121
+ # sidekiq/sidekiq#3243
122
122
  def unfiltered?
123
123
  yield unless env["PATH_INFO"].start_with?("/filter/")
124
124
  end
data/sidekiq.gemspec CHANGED
@@ -2,7 +2,7 @@ require_relative "lib/sidekiq/version"
2
2
 
3
3
  Gem::Specification.new do |gem|
4
4
  gem.authors = ["Mike Perham"]
5
- gem.email = ["mperham@gmail.com"]
5
+ gem.email = ["info@contribsys.com"]
6
6
  gem.summary = "Simple, efficient background processing for Ruby"
7
7
  gem.description = "Simple, efficient background processing for Ruby."
8
8
  gem.homepage = "https://sidekiq.org"
@@ -16,10 +16,10 @@ Gem::Specification.new do |gem|
16
16
 
17
17
  gem.metadata = {
18
18
  "homepage_uri" => "https://sidekiq.org",
19
- "bug_tracker_uri" => "https://github.com/mperham/sidekiq/issues",
20
- "documentation_uri" => "https://github.com/mperham/sidekiq/wiki",
21
- "changelog_uri" => "https://github.com/mperham/sidekiq/blob/main/Changes.md",
22
- "source_code_uri" => "https://github.com/mperham/sidekiq"
19
+ "bug_tracker_uri" => "https://github.com/sidekiq/sidekiq/issues",
20
+ "documentation_uri" => "https://github.com/sidekiq/sidekiq/wiki",
21
+ "changelog_uri" => "https://github.com/sidekiq/sidekiq/blob/main/Changes.md",
22
+ "source_code_uri" => "https://github.com/sidekiq/sidekiq"
23
23
  }
24
24
 
25
25
  gem.add_dependency "redis-client", ">= 0.11.0"
@@ -31,8 +31,8 @@ Gem::Specification.new do |gem|
31
31
  Welcome to Sidekiq 7.0!
32
32
 
33
33
  1. Use `gem 'sidekiq', '<7'` in your Gemfile if you don't want this new version.
34
- 2. Read the release notes at https://github.com/mperham/sidekiq/blob/main/docs/7.0-Upgrade.md
35
- 3. If you have problems, search for open/closed issues at https://github.com/mperham/sidekiq/issues/
34
+ 2. Read the release notes at https://github.com/sidekiq/sidekiq/blob/main/docs/7.0-Upgrade.md
35
+ 3. If you have problems, search for open/closed issues at https://github.com/sidekiq/sidekiq/issues/
36
36
 
37
37
  EOM
38
38
  end
@@ -4,6 +4,14 @@ class JobMetricsOverviewChart extends BaseChart {
4
4
  this.swatches = [];
5
5
  this.visibleKls = options.visibleKls;
6
6
 
7
+ const countBuckets = this.options.labels.length / 60;
8
+ this.labelBuckets = this.options.labels.reduce((acc, label, index) => {
9
+ const bucket = Math.floor(index / countBuckets);
10
+ acc[bucket] = acc[bucket] || [];
11
+ acc[bucket].push(label);
12
+ return acc;
13
+ }, []);
14
+
7
15
  this.init();
8
16
  }
9
17
 
@@ -52,7 +60,7 @@ class JobMetricsOverviewChart extends BaseChart {
52
60
 
53
61
  return {
54
62
  label: kls,
55
- data: this.options.series[kls],
63
+ data: this.buildSeries(kls),
56
64
  borderColor: color,
57
65
  backgroundColor: color,
58
66
  borderWidth: 2,
@@ -60,6 +68,26 @@ class JobMetricsOverviewChart extends BaseChart {
60
68
  };
61
69
  }
62
70
 
71
+ buildSeries(kls) {
72
+ // `series` is an object that maps labels to counts => { "20:15" => 2, "20:16" => 3, ... }
73
+ const series = this.options.series[kls];
74
+ return this.labelBuckets.reduce((acc, labels) => {
75
+ const bucketValues = labels.map(label => series[label]).filter(v => v);
76
+ if (bucketValues.length > 0) {
77
+ // Sum up the values for each bucket that has data.
78
+ // The new label is the bucket's first label, its start time.
79
+ acc[labels[0]] = bucketValues.reduce((a, b) => a + b, 0);
80
+ }
81
+ return acc;
82
+ }, {});
83
+ }
84
+
85
+ buildTooltipTitle(items) {
86
+ const [first, ...rest] = this.labelBuckets.find((labels) => labels[0] === items[0].label);
87
+ const title = [first, rest[rest.length - 1]].filter(v => v).join(" - ");
88
+ return `${title} UTC`
89
+ }
90
+
63
91
  get chartOptions() {
64
92
  return {
65
93
  ...super.chartOptions,
@@ -80,7 +108,7 @@ class JobMetricsOverviewChart extends BaseChart {
80
108
  tooltip: {
81
109
  ...super.chartOptions.plugins.tooltip,
82
110
  callbacks: {
83
- title: (items) => `${items[0].label} UTC`,
111
+ title: (items) => this.buildTooltipTitle(items),
84
112
  label: (item) =>
85
113
  `${item.dataset.label}: ${item.parsed.y.toFixed(1)} ` +
86
114
  `${this.options.units}`,
@@ -72,7 +72,7 @@ h1, h2, h3 {
72
72
  line-height: 45px;
73
73
  }
74
74
 
75
- .header-container {
75
+ .header-container, .header-container .page-title-container {
76
76
  display: flex;
77
77
  justify-content: space-between;
78
78
  align-items: center;
data/web/locales/da.yml CHANGED
@@ -1,11 +1,12 @@
1
1
  # elements like %{queue} are variables and should not be translated
2
2
  da:
3
- Actions: Actions
3
+ Actions: Handlinger
4
4
  AddToQueue: Tilføj til kø
5
5
  AreYouSure: Er du sikker?
6
6
  AreYouSureDeleteJob: Er du sikker på at du vil slette dette job?
7
7
  AreYouSureDeleteQueue: Er du sikker på at du vil slette %{queue} køen?
8
8
  Arguments: Argumenter
9
+ AvgExecutionTime: Gennemsnitlig eksekveringstid
9
10
  Busy: Travl
10
11
  Class: Klasse
11
12
  Connections: Forbindelser
@@ -18,21 +19,25 @@ da:
18
19
  Enqueued: I kø
19
20
  Error: Fejl
20
21
  ErrorBacktrace: Fejl backtrace
21
- ErrorClass: Fejl klasse
22
- ErrorMessage: Fejl besked
22
+ ErrorClass: Fejlklasse
23
+ ErrorMessage: Fejlbesked
23
24
  Extras: Ekstra
24
25
  Failed: Fejlet
26
+ Failure: Fejl
25
27
  Failures: Fejl
26
28
  GoBack: ← Tilbage
27
29
  History: Historik
28
30
  Job: Job
29
31
  Jobs: Jobs
32
+ Latency: Forsinkelse
30
33
  LastRetry: Sidste forsøg
31
34
  LivePoll: Live Poll
32
35
  MemoryUsage: RAM forbrug
36
+ Name: Navn
33
37
  Namespace: Namespace
34
38
  NextRetry: Næste forsøg
35
39
  NoDeadJobsFound: Ingen døde jobs fundet
40
+ NoJobMetricsFound: Ingen nylig job-metrics blev fundet
36
41
  NoRetriesFound: Ingen gen-forsøg var fundet
37
42
  NoScheduledFound: Ingen jobs i kø fundet
38
43
  OneMonth: 1 måned
@@ -43,7 +48,7 @@ da:
43
48
  Processes: Processer
44
49
  Queue: Kø
45
50
  Queues: Køer
46
- Realtime: Real-time
51
+ Realtime: Realtid
47
52
  Retries: Forsøg
48
53
  RetryAll: Forsøg alle
49
54
  RetryCount: Antal forsøg
@@ -56,10 +61,12 @@ da:
56
61
  Started: Startet
57
62
  Status: Status
58
63
  StopPolling: Stop Polling
64
+ Success: Succes
59
65
  Thread: Tråd
60
66
  Threads: Tråde
61
67
  ThreeMonths: 3 måneder
62
68
  Time: Tid
69
+ TotalExecutionTime: Total eksekveringstid
63
70
  Uptime: Oppetid (dage)
64
71
  Version: Version
65
72
  When: Når
@@ -12,10 +12,10 @@
12
12
  <p id="serverUtcTime" class="navbar-text server-utc-time"><%= server_utc_time %></p>
13
13
  </li>
14
14
  <li>
15
- <p class="navbar-text"><a rel=help href="https://github.com/mperham/sidekiq/wiki">docs</a></p>
15
+ <p class="navbar-text"><a rel=help href="https://github.com/sidekiq/sidekiq/wiki">docs</a></p>
16
16
  </li>
17
17
  <li>
18
- <p class="navbar-text"><a rel=external href="https://github.com/mperham/sidekiq/tree/main/web/locales"><%= locale %></a></p>
18
+ <p class="navbar-text"><a rel=external href="https://github.com/sidekiq/sidekiq/tree/main/web/locales"><%= locale %></a></p>
19
19
  </li>
20
20
  </ul>
21
21
  </div>
@@ -0,0 +1,12 @@
1
+ <div>
2
+ <select class="form-control" onchange="window.location.href = '<%= path %>?period=' + event.target.value">
3
+ <% periods.each_key do |code| %>
4
+
5
+ <% if code == period %>
6
+ <option selected value="<%= code %>"><%= code %></option>
7
+ <% else %>
8
+ <option value="<%= code %>"><%= code %></option>
9
+ <% end %>
10
+ <% end %>
11
+ </select>
12
+ </div>
data/web/views/busy.erb CHANGED
@@ -45,7 +45,7 @@
45
45
  <thead>
46
46
  <th><%= t('Name') %></th>
47
47
  <th><%= t('Started') %></th>
48
- <th class="col-sm-1"><%= t('RSS') %><a target="blank" href="https://github.com/mperham/sidekiq/wiki/Memory#rss"><span class="info-circle" title="Click to learn more about RSS">?</span></a></th>
48
+ <th class="col-sm-1"><%= t('RSS') %><a target="blank" href="https://github.com/sidekiq/sidekiq/wiki/Memory#rss"><span class="info-circle" title="Click to learn more about RSS">?</span></a></th>
49
49
  <th class="col-sm-1"><%= t('Threads') %></th>
50
50
  <th class="col-sm-1"><%= t('Busy') %></th>
51
51
  <th>&nbsp;</th>
@@ -4,11 +4,13 @@
4
4
  <script type="text/javascript" src="<%= root_path %>javascripts/metrics.js"></script>
5
5
 
6
6
  <div class="header-container">
7
- <h1><%= t('Metrics') %></h1>
7
+ <div class="page-title-container">
8
+ <h1><%= t('Metrics') %></h1>
8
9
 
9
- <div>
10
- <a target="blank" href="https://github.com/mperham/sidekiq/wiki/Metrics"><span class="info-circle" title="Click to learn more about metrics">?</span></a>
10
+ <a target="blank" href="https://github.com/sidekiq/sidekiq/wiki/Metrics"><span class="info-circle" title="Click to learn more about metrics">?</span></a>
11
11
  </div>
12
+
13
+ <%= erb :_metrics_period_select, locals: { periods: @periods, period: @period, path: "#{root_path}metrics" } %>
12
14
  </div>
13
15
 
14
16
  <%
@@ -60,7 +62,7 @@
60
62
  value="<%= kls %>"
61
63
  <%= visible_kls.include?(kls) ? 'checked' : '' %>
62
64
  />
63
- <code><a href="<%= root_path %>metrics/<%= kls %>"><%= kls %></a></code>
65
+ <code><a href="<%= root_path %>metrics/<%= kls %>?period=<%= @period %>"><%= kls %></a></code>
64
66
  </div>
65
67
  <script>jobMetricsChart.registerSwatch("<%= id %>")</script>
66
68
  </td>
@@ -15,14 +15,16 @@
15
15
 
16
16
  <% if job_result.totals["s"] > 0 %>
17
17
  <div class="header-container">
18
- <h1>
19
- <a href="<%= root_path %>metrics"><%= t('Metrics') %></a> /
20
- <%= h @name %>
21
- </h1>
18
+ <div class="page-title-container">
19
+ <h1>
20
+ <a href="<%= root_path %>metrics?period=<%= @period %>"><%= t('Metrics') %></a> /
21
+ <%= h @name %>
22
+ </h1>
22
23
 
23
- <div>
24
- <a target="blank" href="https://github.com/mperham/sidekiq/wiki/Metrics"><span class="info-circle" title="Click to learn more about metrics">?</span></a>
24
+ <a target="blank" href="https://github.com/sidekiq/sidekiq/wiki/Metrics"><span class="info-circle" title="Click to learn more about metrics">?</span></a>
25
25
  </div>
26
+
27
+ <%= erb :_metrics_period_select, locals: { periods: @periods, period: @period, path: "#{root_path}metrics/#{@name}" } %>
26
28
  </div>
27
29
 
28
30
  <canvas id="hist-totals-chart"></canvas>
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.0.3
4
+ version: 7.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Perham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-11 00:00:00.000000000 Z
11
+ date: 2023-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis-client
@@ -68,7 +68,7 @@ dependencies:
68
68
  version: '2'
69
69
  description: Simple, efficient background processing for Ruby.
70
70
  email:
71
- - mperham@gmail.com
71
+ - info@contribsys.com
72
72
  executables:
73
73
  - sidekiq
74
74
  - sidekiqmon
@@ -177,6 +177,7 @@ files:
177
177
  - web/locales/zh-tw.yml
178
178
  - web/views/_footer.erb
179
179
  - web/views/_job_info.erb
180
+ - web/views/_metrics_period_select.erb
180
181
  - web/views/_nav.erb
181
182
  - web/views/_paging.erb
182
183
  - web/views/_poll_link.erb
@@ -200,17 +201,17 @@ licenses:
200
201
  - LGPL-3.0
201
202
  metadata:
202
203
  homepage_uri: https://sidekiq.org
203
- bug_tracker_uri: https://github.com/mperham/sidekiq/issues
204
- documentation_uri: https://github.com/mperham/sidekiq/wiki
205
- changelog_uri: https://github.com/mperham/sidekiq/blob/main/Changes.md
206
- source_code_uri: https://github.com/mperham/sidekiq
204
+ bug_tracker_uri: https://github.com/sidekiq/sidekiq/issues
205
+ documentation_uri: https://github.com/sidekiq/sidekiq/wiki
206
+ changelog_uri: https://github.com/sidekiq/sidekiq/blob/main/Changes.md
207
+ source_code_uri: https://github.com/sidekiq/sidekiq
207
208
  post_install_message: |2+
208
209
 
209
210
  Welcome to Sidekiq 7.0!
210
211
 
211
212
  1. Use `gem 'sidekiq', '<7'` in your Gemfile if you don't want this new version.
212
- 2. Read the release notes at https://github.com/mperham/sidekiq/blob/main/docs/7.0-Upgrade.md
213
- 3. If you have problems, search for open/closed issues at https://github.com/mperham/sidekiq/issues/
213
+ 2. Read the release notes at https://github.com/sidekiq/sidekiq/blob/main/docs/7.0-Upgrade.md
214
+ 3. If you have problems, search for open/closed issues at https://github.com/sidekiq/sidekiq/issues/
214
215
 
215
216
  rdoc_options: []
216
217
  require_paths:
@@ -226,7 +227,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
226
227
  - !ruby/object:Gem::Version
227
228
  version: '0'
228
229
  requirements: []
229
- rubygems_version: 3.2.32
230
+ rubygems_version: 3.4.6
230
231
  signing_key:
231
232
  specification_version: 4
232
233
  summary: Simple, efficient background processing for Ruby