sidekiq 6.2.2 → 6.4.1
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 +4 -4
- data/Changes.md +76 -1
- data/LICENSE +3 -3
- data/README.md +8 -3
- data/bin/sidekiq +3 -3
- data/bin/sidekiqload +56 -58
- data/bin/sidekiqmon +1 -1
- data/lib/generators/sidekiq/job_generator.rb +57 -0
- data/lib/generators/sidekiq/templates/{worker.rb.erb → job.rb.erb} +2 -2
- data/lib/generators/sidekiq/templates/{worker_spec.rb.erb → job_spec.rb.erb} +1 -1
- data/lib/generators/sidekiq/templates/{worker_test.rb.erb → job_test.rb.erb} +1 -1
- data/lib/sidekiq/api.rb +50 -43
- data/lib/sidekiq/cli.rb +23 -5
- data/lib/sidekiq/client.rb +22 -41
- data/lib/sidekiq/delay.rb +2 -0
- data/lib/sidekiq/fetch.rb +6 -5
- data/lib/sidekiq/job.rb +8 -3
- data/lib/sidekiq/job_logger.rb +15 -27
- data/lib/sidekiq/job_retry.rb +6 -4
- data/lib/sidekiq/job_util.rb +65 -0
- data/lib/sidekiq/launcher.rb +32 -28
- data/lib/sidekiq/logger.rb +4 -0
- data/lib/sidekiq/manager.rb +7 -9
- data/lib/sidekiq/middleware/current_attributes.rb +57 -0
- data/lib/sidekiq/paginator.rb +8 -8
- data/lib/sidekiq/rails.rb +11 -0
- data/lib/sidekiq/redis_connection.rb +4 -6
- data/lib/sidekiq/scheduled.rb +44 -15
- data/lib/sidekiq/util.rb +13 -0
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web/application.rb +7 -4
- data/lib/sidekiq/web/helpers.rb +2 -13
- data/lib/sidekiq/web.rb +3 -3
- data/lib/sidekiq/worker.rb +125 -7
- data/lib/sidekiq.rb +9 -1
- data/sidekiq.gemspec +1 -1
- data/web/assets/javascripts/application.js +82 -61
- data/web/assets/javascripts/dashboard.js +51 -51
- data/web/assets/stylesheets/application-dark.css +19 -23
- data/web/assets/stylesheets/application-rtl.css +0 -4
- data/web/assets/stylesheets/application.css +12 -108
- data/web/locales/en.yml +1 -1
- data/web/views/_footer.erb +1 -1
- data/web/views/_poll_link.erb +2 -5
- data/web/views/_summary.erb +7 -7
- data/web/views/dashboard.erb +8 -8
- data/web/views/layout.erb +1 -1
- data/web/views/queue.erb +10 -10
- data/web/views/queues.erb +1 -1
- metadata +10 -8
- data/lib/generators/sidekiq/worker_generator.rb +0 -57
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99c9e264c092b88ea726be158fafe5bbab91f82f4b5864dee406280622e98e4b
|
4
|
+
data.tar.gz: acd72bd99929d7c9d129cb9662276cc5adb7214de07cd4fc8accf6b9d521994a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 622c25276c017302c1a9d144e9366043ba359b2c3b0c57d4e7baad8f9de2e9c9969a86c91acdbefcf736af92e297c4e1fbe2008aa41e0c1accadda77dd0724f5
|
7
|
+
data.tar.gz: 7e64012a5368cb0158ecaa50cdea6447709a64dd3a2816b36a31e7f17d70fffff81bd8d317c0cc1f9a6317adcffad9c200c48f9ca4bf208afba819ff7a07738e
|
data/Changes.md
CHANGED
@@ -1,6 +1,81 @@
|
|
1
1
|
# Sidekiq Changes
|
2
2
|
|
3
|
-
[Sidekiq Changes](https://github.com/mperham/sidekiq/blob/
|
3
|
+
[Sidekiq Changes](https://github.com/mperham/sidekiq/blob/main/Changes.md) | [Sidekiq Pro Changes](https://github.com/mperham/sidekiq/blob/main/Pro-Changes.md) | [Sidekiq Enterprise Changes](https://github.com/mperham/sidekiq/blob/main/Ent-Changes.md)
|
4
|
+
|
5
|
+
HEAD
|
6
|
+
---------
|
7
|
+
|
8
|
+
- Fix pipeline/multi deprecations in redis-rb 4.6
|
9
|
+
- Fix sidekiq.yml YAML load errors on Ruby 3.1 [#5141]
|
10
|
+
- Sharding support for `perform_bulk` [#5129]
|
11
|
+
- Refactor job logger for SPEEEEEEED
|
12
|
+
|
13
|
+
6.4.0
|
14
|
+
---------
|
15
|
+
|
16
|
+
- **SECURITY**: Validate input to avoid possible DoS in Web UI.
|
17
|
+
- Add **strict argument checking** [#5071]
|
18
|
+
Sidekiq will now log a warning if JSON-unsafe arguments are passed to `perform_async`.
|
19
|
+
Add `Sidekiq.strict_args!(false)` to your initializer to disable this warning.
|
20
|
+
This warning will switch to an exception in Sidekiq 7.0.
|
21
|
+
- Note that Delayed Extensions will be removed in Sidekiq 7.0 [#5076]
|
22
|
+
- Add `perform_{inline,sync}` in Sidekiq::Job to run a job synchronously [#5061, hasan-ally]
|
23
|
+
```ruby
|
24
|
+
SomeJob.perform_async(args...)
|
25
|
+
SomeJob.perform_sync(args...)
|
26
|
+
SomeJob.perform_inline(args...)
|
27
|
+
```
|
28
|
+
You can also dynamically redirect a job to run synchronously:
|
29
|
+
```ruby
|
30
|
+
SomeJob.set("sync": true).perform_async(args...) # will run via perform_inline
|
31
|
+
```
|
32
|
+
- Replace Sidekiq::Worker `app/workers` generator with Sidekiq::Job `app/sidekiq` generator [#5055]
|
33
|
+
```
|
34
|
+
bin/rails generate sidekiq:job ProcessOrderJob
|
35
|
+
```
|
36
|
+
- Fix job retries losing CurrentAttributes [#5090]
|
37
|
+
- Tweak shutdown to give long-running threads time to cleanup [#5095]
|
38
|
+
|
39
|
+
6.3.1
|
40
|
+
---------
|
41
|
+
|
42
|
+
- Fix keyword arguments error with CurrentAttributes on Ruby 3.0 [#5048]
|
43
|
+
|
44
|
+
6.3.0
|
45
|
+
---------
|
46
|
+
|
47
|
+
- **BREAK**: The Web UI has been refactored to remove jQuery. Any UI extensions
|
48
|
+
which use jQuery will break.
|
49
|
+
- **FEATURE**: Sidekiq.logger has been enhanced so any `Rails.logger`
|
50
|
+
output in jobs now shows up in the Sidekiq console. Remove any logger
|
51
|
+
hacks in your initializer and see if it Just Works™ now. [#5021]
|
52
|
+
- **FEATURE**: Add `Sidekiq::Job` alias for `Sidekiq::Worker`, to better
|
53
|
+
reflect industry standard terminology. You can now do this:
|
54
|
+
```ruby
|
55
|
+
class MyJob
|
56
|
+
include Sidekiq::Job
|
57
|
+
sidekiq_options ...
|
58
|
+
def perform(args)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
```
|
62
|
+
- **FEATURE**: Support for serializing ActiveSupport::CurrentAttributes into each job. [#4982]
|
63
|
+
```ruby
|
64
|
+
# config/initializers/sidekiq.rb
|
65
|
+
require "sidekiq/middleware/current_attributes"
|
66
|
+
Sidekiq::CurrentAttributes.persist(Myapp::Current) # Your AS::CurrentAttributes singleton
|
67
|
+
```
|
68
|
+
- **FEATURE**: Add `Sidekiq::Worker.perform_bulk` for enqueuing jobs in bulk,
|
69
|
+
similar to `Sidekiq::Client.push_bulk` [#5042]
|
70
|
+
```ruby
|
71
|
+
MyJob.perform_bulk([[1], [2], [3]])
|
72
|
+
```
|
73
|
+
- Implement `queue_as`, `wait` and `wait_until` for ActiveJob compatibility [#5003]
|
74
|
+
- Scheduler now uses Lua to reduce Redis load and network roundtrips [#5044]
|
75
|
+
- Retry Redis operation if we get an `UNBLOCKED` Redis error [#4985]
|
76
|
+
- Run existing signal traps, if any, before running Sidekiq's trap [#4991]
|
77
|
+
- Fix fetch bug when using weighted queues which caused Sidekiq to stop
|
78
|
+
processing queues randomly [#5031]
|
4
79
|
|
5
80
|
6.2.2
|
6
81
|
---------
|
data/LICENSE
CHANGED
@@ -4,6 +4,6 @@ Sidekiq is an Open Source project licensed under the terms of
|
|
4
4
|
the LGPLv3 license. Please see <http://www.gnu.org/licenses/lgpl-3.0.html>
|
5
5
|
for license text.
|
6
6
|
|
7
|
-
Sidekiq Pro
|
8
|
-
|
9
|
-
|
7
|
+
Sidekiq Pro and Sidekiq Enterprise have a commercial-friendly license.
|
8
|
+
You can find the commercial license in COMM-LICENSE.txt.
|
9
|
+
Please see https://sidekiq.org for purchasing options.
|
data/README.md
CHANGED
@@ -43,10 +43,10 @@ Getting Started
|
|
43
43
|
-----------------
|
44
44
|
|
45
45
|
See the [Getting Started wiki page](https://github.com/mperham/sidekiq/wiki/Getting-Started) and follow the simple setup process.
|
46
|
-
You can watch [this
|
46
|
+
You can watch [this YouTube playlist](https://www.youtube.com/playlist?list=PLjeHh2LSCFrWGT5uVjUuFKAcrcj5kSai1) to learn all about
|
47
47
|
Sidekiq and see its features in action. Here's the Web UI:
|
48
48
|
|
49
|
-
![Web UI](https://github.com/mperham/sidekiq/raw/
|
49
|
+
![Web UI](https://github.com/mperham/sidekiq/raw/main/examples/web-ui.png)
|
50
50
|
|
51
51
|
|
52
52
|
Want to Upgrade?
|
@@ -80,11 +80,16 @@ Useful resources:
|
|
80
80
|
Every Friday morning is Sidekiq happy hour: I video chat and answer questions.
|
81
81
|
See the [Sidekiq support page](https://sidekiq.org/support.html) for details.
|
82
82
|
|
83
|
+
Contributing
|
84
|
+
-----------------
|
85
|
+
|
86
|
+
Please see [the contributing guidelines](https://github.com/mperham/sidekiq/blob/main/.github/contributing.md).
|
87
|
+
|
83
88
|
|
84
89
|
License
|
85
90
|
-----------------
|
86
91
|
|
87
|
-
Please see [LICENSE](https://github.com/mperham/sidekiq/blob/
|
92
|
+
Please see [LICENSE](https://github.com/mperham/sidekiq/blob/main/LICENSE) for licensing details.
|
88
93
|
|
89
94
|
|
90
95
|
Author
|
data/bin/sidekiq
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
# RUBYOPT=-w bundle exec sidekiq
|
5
5
|
$TESTING = false
|
6
6
|
|
7
|
-
require_relative
|
7
|
+
require_relative "../lib/sidekiq/cli"
|
8
8
|
|
9
9
|
def integrate_with_systemd
|
10
10
|
return unless ENV["NOTIFY_SOCKET"]
|
@@ -32,8 +32,8 @@ begin
|
|
32
32
|
rescue => e
|
33
33
|
raise e if $DEBUG
|
34
34
|
if Sidekiq.error_handlers.length == 0
|
35
|
-
|
36
|
-
|
35
|
+
warn e.message
|
36
|
+
warn e.backtrace.join("\n")
|
37
37
|
else
|
38
38
|
cli.handle_exception e
|
39
39
|
end
|
data/bin/sidekiqload
CHANGED
@@ -4,19 +4,18 @@
|
|
4
4
|
# RUBYOPT=-w bundle exec sidekiq
|
5
5
|
$TESTING = false
|
6
6
|
|
7
|
-
#require
|
8
|
-
require
|
7
|
+
# require "ruby-prof"
|
8
|
+
require "bundler/setup"
|
9
9
|
Bundler.require(:default, :load_test)
|
10
10
|
|
11
|
-
require_relative
|
12
|
-
require_relative
|
13
|
-
|
14
|
-
include Sidekiq::Util
|
11
|
+
require_relative "../lib/sidekiq/cli"
|
12
|
+
require_relative "../lib/sidekiq/launcher"
|
15
13
|
|
16
14
|
Sidekiq.configure_server do |config|
|
17
15
|
config.options[:concurrency] = 10
|
18
|
-
config.redis = {
|
19
|
-
config.
|
16
|
+
config.redis = {db: 13, port: 6380}
|
17
|
+
# config.redis = { db: 13, port: 6380, driver: :hiredis}
|
18
|
+
config.options[:queues] << "default"
|
20
19
|
config.logger.level = Logger::ERROR
|
21
20
|
config.average_scheduled_poll_interval = 2
|
22
21
|
config.reliable! if defined?(Sidekiq::Pro)
|
@@ -29,9 +28,9 @@ class LoadWorker
|
|
29
28
|
1
|
30
29
|
end
|
31
30
|
|
32
|
-
def perform(idx, ts=nil)
|
33
|
-
puts(Time.now.to_f - ts) if ts
|
34
|
-
#raise idx.to_s if idx % 100 == 1
|
31
|
+
def perform(idx, ts = nil)
|
32
|
+
puts(Time.now.to_f - ts) if !ts.nil?
|
33
|
+
# raise idx.to_s if idx % 100 == 1
|
35
34
|
end
|
36
35
|
end
|
37
36
|
|
@@ -39,43 +38,41 @@ end
|
|
39
38
|
# brew install toxiproxy
|
40
39
|
# gem install toxiproxy
|
41
40
|
# run `toxiproxy-server` in a separate terminal window.
|
42
|
-
require
|
41
|
+
require "toxiproxy"
|
43
42
|
# simulate a non-localhost network for realer-world conditions.
|
44
43
|
# adding 1ms of network latency has an ENORMOUS impact on benchmarks
|
45
44
|
Toxiproxy.populate([{
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
name: "redis",
|
46
|
+
listen: "127.0.0.1:6380",
|
47
|
+
upstream: "127.0.0.1:6379"
|
49
48
|
}])
|
50
49
|
|
51
50
|
self_read, self_write = IO.pipe
|
52
|
-
%w
|
53
|
-
|
54
|
-
|
55
|
-
self_write.puts(sig)
|
56
|
-
end
|
57
|
-
rescue ArgumentError
|
58
|
-
puts "Signal #{sig} not supported"
|
51
|
+
%w[INT TERM TSTP TTIN].each do |sig|
|
52
|
+
trap sig do
|
53
|
+
self_write.puts(sig)
|
59
54
|
end
|
55
|
+
rescue ArgumentError
|
56
|
+
puts "Signal #{sig} not supported"
|
60
57
|
end
|
61
58
|
|
62
|
-
Sidekiq.redis {|c| c.flushdb}
|
59
|
+
Sidekiq.redis { |c| c.flushdb }
|
63
60
|
def handle_signal(launcher, sig)
|
64
61
|
Sidekiq.logger.debug "Got #{sig} signal"
|
65
62
|
case sig
|
66
|
-
when
|
63
|
+
when "INT"
|
67
64
|
# Handle Ctrl-C in JRuby like MRI
|
68
65
|
# http://jira.codehaus.org/browse/JRUBY-4637
|
69
66
|
raise Interrupt
|
70
|
-
when
|
67
|
+
when "TERM"
|
71
68
|
# Heroku sends TERM and then waits 30 seconds for process to exit.
|
72
69
|
raise Interrupt
|
73
|
-
when
|
70
|
+
when "TSTP"
|
74
71
|
Sidekiq.logger.info "Received TSTP, no longer accepting new work"
|
75
72
|
launcher.quiet
|
76
|
-
when
|
73
|
+
when "TTIN"
|
77
74
|
Thread.list.each do |thread|
|
78
|
-
Sidekiq.logger.warn "Thread TID-#{(thread.object_id ^ ::Process.pid).to_s(36)} #{thread[
|
75
|
+
Sidekiq.logger.warn "Thread TID-#{(thread.object_id ^ ::Process.pid).to_s(36)} #{thread["label"]}"
|
79
76
|
if thread.backtrace
|
80
77
|
Sidekiq.logger.warn thread.backtrace.join("\n")
|
81
78
|
else
|
@@ -89,7 +86,7 @@ def Process.rss
|
|
89
86
|
`ps -o rss= -p #{Process.pid}`.chomp.to_i
|
90
87
|
end
|
91
88
|
|
92
|
-
iter =
|
89
|
+
iter = 50
|
93
90
|
count = 10_000
|
94
91
|
|
95
92
|
iter.times do
|
@@ -99,40 +96,41 @@ iter.times do
|
|
99
96
|
count.times do |idx|
|
100
97
|
arr[idx][0] = idx
|
101
98
|
end
|
102
|
-
Sidekiq::Client.push_bulk(
|
99
|
+
Sidekiq::Client.push_bulk("class" => LoadWorker, "args" => arr)
|
103
100
|
end
|
104
|
-
Sidekiq.logger.error "Created #{count*iter} jobs"
|
101
|
+
Sidekiq.logger.error "Created #{count * iter} jobs"
|
105
102
|
|
106
103
|
start = Time.now
|
107
104
|
|
108
105
|
Monitoring = Thread.new do
|
109
|
-
|
110
|
-
|
106
|
+
while true
|
107
|
+
sleep 0.2
|
108
|
+
qsize = Sidekiq.redis do |conn|
|
109
|
+
conn.llen "queue:default"
|
110
|
+
end
|
111
|
+
total = qsize
|
112
|
+
# Sidekiq.logger.error("RSS: #{Process.rss} Pending: #{total}")
|
113
|
+
if total == 0
|
114
|
+
Sidekiq.logger.error("Done, #{iter * count} jobs in #{Time.now - start} sec")
|
115
|
+
Sidekiq.logger.error("Now here's the latency for three jobs")
|
116
|
+
|
117
|
+
LoadWorker.perform_async(1, Time.now.to_f)
|
118
|
+
LoadWorker.perform_async(2, Time.now.to_f)
|
119
|
+
LoadWorker.perform_async(3, Time.now.to_f)
|
120
|
+
|
111
121
|
sleep 0.2
|
112
|
-
|
113
|
-
conn.llen "queue:default"
|
114
|
-
end
|
115
|
-
total = qsize
|
116
|
-
#Sidekiq.logger.error("RSS: #{Process.rss} Pending: #{total}")
|
117
|
-
if total == 0
|
118
|
-
Sidekiq.logger.error("Done, #{iter * count} jobs in #{Time.now - start} sec")
|
119
|
-
Sidekiq.logger.error("Now here's the latency for three jobs")
|
120
|
-
|
121
|
-
LoadWorker.perform_async(1, Time.now.to_f)
|
122
|
-
LoadWorker.perform_async(2, Time.now.to_f)
|
123
|
-
LoadWorker.perform_async(3, Time.now.to_f)
|
124
|
-
|
125
|
-
sleep 0.2
|
126
|
-
exit(0)
|
127
|
-
end
|
122
|
+
exit(0)
|
128
123
|
end
|
129
124
|
end
|
130
125
|
end
|
131
126
|
|
132
127
|
begin
|
133
|
-
#RubyProf::exclude_threads = [ Monitoring ]
|
134
|
-
#RubyProf.start
|
135
|
-
|
128
|
+
# RubyProf::exclude_threads = [ Monitoring ]
|
129
|
+
# RubyProf.start
|
130
|
+
events = Sidekiq.options[:lifecycle_events][:startup]
|
131
|
+
events.each(&:call)
|
132
|
+
events.clear
|
133
|
+
|
136
134
|
Sidekiq.logger.error "Simulating 1ms of latency between Sidekiq and redis"
|
137
135
|
Toxiproxy[:redis].downstream(:latency, latency: 1).apply do
|
138
136
|
launcher = Sidekiq::Launcher.new(Sidekiq.options)
|
@@ -144,14 +142,14 @@ begin
|
|
144
142
|
end
|
145
143
|
end
|
146
144
|
rescue SystemExit => e
|
147
|
-
#Sidekiq.logger.error("Profiling...")
|
148
|
-
#result = RubyProf.stop
|
149
|
-
#printer = RubyProf::GraphHtmlPrinter.new(result)
|
150
|
-
#printer.print(File.new("output.html", "w"), :min_percent => 1)
|
145
|
+
# Sidekiq.logger.error("Profiling...")
|
146
|
+
# result = RubyProf.stop
|
147
|
+
# printer = RubyProf::GraphHtmlPrinter.new(result)
|
148
|
+
# printer.print(File.new("output.html", "w"), :min_percent => 1)
|
151
149
|
# normal
|
152
150
|
rescue => e
|
153
151
|
raise e if $DEBUG
|
154
|
-
|
155
|
-
|
152
|
+
warn e.message
|
153
|
+
warn e.backtrace.join("\n")
|
156
154
|
exit 1
|
157
155
|
end
|
data/bin/sidekiqmon
CHANGED
@@ -0,0 +1,57 @@
|
|
1
|
+
require "rails/generators/named_base"
|
2
|
+
|
3
|
+
module Sidekiq
|
4
|
+
module Generators # :nodoc:
|
5
|
+
class JobGenerator < ::Rails::Generators::NamedBase # :nodoc:
|
6
|
+
desc "This generator creates a Sidekiq Job in app/sidekiq and a corresponding test"
|
7
|
+
|
8
|
+
check_class_collision suffix: "Job"
|
9
|
+
|
10
|
+
def self.default_generator_root
|
11
|
+
File.dirname(__FILE__)
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_job_file
|
15
|
+
template "job.rb.erb", File.join("app/sidekiq", class_path, "#{file_name}_job.rb")
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_test_file
|
19
|
+
return unless test_framework
|
20
|
+
|
21
|
+
if test_framework == :rspec
|
22
|
+
create_job_spec
|
23
|
+
else
|
24
|
+
create_job_test
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def create_job_spec
|
31
|
+
template_file = File.join(
|
32
|
+
"spec/sidekiq",
|
33
|
+
class_path,
|
34
|
+
"#{file_name}_job_spec.rb"
|
35
|
+
)
|
36
|
+
template "job_spec.rb.erb", template_file
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_job_test
|
40
|
+
template_file = File.join(
|
41
|
+
"test/sidekiq",
|
42
|
+
class_path,
|
43
|
+
"#{file_name}_job_test.rb"
|
44
|
+
)
|
45
|
+
template "job_test.rb.erb", template_file
|
46
|
+
end
|
47
|
+
|
48
|
+
def file_name
|
49
|
+
@_file_name ||= super.sub(/_?job\z/i, "")
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_framework
|
53
|
+
::Rails.application.config.generators.options[:rails][:test_framework]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/sidekiq/api.rb
CHANGED
@@ -54,14 +54,14 @@ module Sidekiq
|
|
54
54
|
# O(1) redis calls
|
55
55
|
def fetch_stats_fast!
|
56
56
|
pipe1_res = Sidekiq.redis { |conn|
|
57
|
-
conn.pipelined do
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
57
|
+
conn.pipelined do |pipeline|
|
58
|
+
pipeline.get("stat:processed")
|
59
|
+
pipeline.get("stat:failed")
|
60
|
+
pipeline.zcard("schedule")
|
61
|
+
pipeline.zcard("retry")
|
62
|
+
pipeline.zcard("dead")
|
63
|
+
pipeline.scard("processes")
|
64
|
+
pipeline.lrange("queue:default", -1, -1)
|
65
65
|
end
|
66
66
|
}
|
67
67
|
|
@@ -101,9 +101,9 @@ module Sidekiq
|
|
101
101
|
}
|
102
102
|
|
103
103
|
pipe2_res = Sidekiq.redis { |conn|
|
104
|
-
conn.pipelined do
|
105
|
-
processes.each { |key|
|
106
|
-
queues.each { |queue|
|
104
|
+
conn.pipelined do |pipeline|
|
105
|
+
processes.each { |key| pipeline.hget(key, "busy") }
|
106
|
+
queues.each { |queue| pipeline.llen("queue:#{queue}") }
|
107
107
|
end
|
108
108
|
}
|
109
109
|
|
@@ -113,6 +113,7 @@ module Sidekiq
|
|
113
113
|
|
114
114
|
@stats[:workers_size] = workers_size
|
115
115
|
@stats[:enqueued] = enqueued
|
116
|
+
@stats
|
116
117
|
end
|
117
118
|
|
118
119
|
def fetch_stats!
|
@@ -146,9 +147,9 @@ module Sidekiq
|
|
146
147
|
Sidekiq.redis do |conn|
|
147
148
|
queues = conn.sscan_each("queues").to_a
|
148
149
|
|
149
|
-
lengths = conn.pipelined {
|
150
|
+
lengths = conn.pipelined { |pipeline|
|
150
151
|
queues.each do |queue|
|
151
|
-
|
152
|
+
pipeline.llen("queue:#{queue}")
|
152
153
|
end
|
153
154
|
}
|
154
155
|
|
@@ -160,6 +161,8 @@ module Sidekiq
|
|
160
161
|
|
161
162
|
class History
|
162
163
|
def initialize(days_previous, start_date = nil)
|
164
|
+
# we only store five years of data in Redis
|
165
|
+
raise ArgumentError if days_previous < 1 || days_previous > (5 * 365)
|
163
166
|
@days_previous = days_previous
|
164
167
|
@start_date = start_date || Time.now.utc.to_date
|
165
168
|
end
|
@@ -284,9 +287,9 @@ module Sidekiq
|
|
284
287
|
|
285
288
|
def clear
|
286
289
|
Sidekiq.redis do |conn|
|
287
|
-
conn.multi do
|
288
|
-
|
289
|
-
|
290
|
+
conn.multi do |transaction|
|
291
|
+
transaction.unlink(@rname)
|
292
|
+
transaction.srem("queues", name)
|
290
293
|
end
|
291
294
|
end
|
292
295
|
end
|
@@ -352,8 +355,12 @@ module Sidekiq
|
|
352
355
|
# Unwrap known wrappers so they show up in a human-friendly manner in the Web UI
|
353
356
|
@display_args ||= case klass
|
354
357
|
when /\ASidekiq::Extensions::Delayed/
|
355
|
-
safe_load(args[0], args) do |_, _, arg|
|
356
|
-
|
358
|
+
safe_load(args[0], args) do |_, _, arg, kwarg|
|
359
|
+
if !kwarg || kwarg.empty?
|
360
|
+
arg
|
361
|
+
else
|
362
|
+
[arg, kwarg]
|
363
|
+
end
|
357
364
|
end
|
358
365
|
when "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper"
|
359
366
|
job_args = self["wrapped"] ? args[0]["arguments"] : []
|
@@ -516,9 +523,9 @@ module Sidekiq
|
|
516
523
|
|
517
524
|
def remove_job
|
518
525
|
Sidekiq.redis do |conn|
|
519
|
-
results = conn.multi {
|
520
|
-
|
521
|
-
|
526
|
+
results = conn.multi { |transaction|
|
527
|
+
transaction.zrangebyscore(parent.name, score, score)
|
528
|
+
transaction.zremrangebyscore(parent.name, score, score)
|
522
529
|
}.first
|
523
530
|
|
524
531
|
if results.size == 1
|
@@ -539,9 +546,9 @@ module Sidekiq
|
|
539
546
|
yield msg if msg
|
540
547
|
|
541
548
|
# push the rest back onto the sorted set
|
542
|
-
conn.multi do
|
549
|
+
conn.multi do |transaction|
|
543
550
|
nonmatched.each do |message|
|
544
|
-
|
551
|
+
transaction.zadd(parent.name, score.to_f.to_s, message)
|
545
552
|
end
|
546
553
|
end
|
547
554
|
end
|
@@ -728,10 +735,10 @@ module Sidekiq
|
|
728
735
|
def kill(message, opts = {})
|
729
736
|
now = Time.now.to_f
|
730
737
|
Sidekiq.redis do |conn|
|
731
|
-
conn.multi do
|
732
|
-
|
733
|
-
|
734
|
-
|
738
|
+
conn.multi do |transaction|
|
739
|
+
transaction.zadd(name, now.to_s, message)
|
740
|
+
transaction.zremrangebyscore(name, "-inf", now - self.class.timeout)
|
741
|
+
transaction.zremrangebyrank(name, 0, - self.class.max_jobs)
|
735
742
|
end
|
736
743
|
end
|
737
744
|
|
@@ -779,9 +786,9 @@ module Sidekiq
|
|
779
786
|
count = 0
|
780
787
|
Sidekiq.redis do |conn|
|
781
788
|
procs = conn.sscan_each("processes").to_a.sort
|
782
|
-
heartbeats = conn.pipelined {
|
789
|
+
heartbeats = conn.pipelined { |pipeline|
|
783
790
|
procs.each do |key|
|
784
|
-
|
791
|
+
pipeline.hget(key, "info")
|
785
792
|
end
|
786
793
|
}
|
787
794
|
|
@@ -803,9 +810,9 @@ module Sidekiq
|
|
803
810
|
# We're making a tradeoff here between consuming more memory instead of
|
804
811
|
# making more roundtrips to Redis, but if you have hundreds or thousands of workers,
|
805
812
|
# you'll be happier this way
|
806
|
-
conn.pipelined do
|
813
|
+
conn.pipelined do |pipeline|
|
807
814
|
procs.each do |key|
|
808
|
-
|
815
|
+
pipeline.hmget(key, "info", "busy", "beat", "quiet", "rss", "rtt_us")
|
809
816
|
end
|
810
817
|
end
|
811
818
|
}
|
@@ -818,10 +825,10 @@ module Sidekiq
|
|
818
825
|
|
819
826
|
hash = Sidekiq.load_json(info)
|
820
827
|
yield Process.new(hash.merge("busy" => busy.to_i,
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
828
|
+
"beat" => at_s.to_f,
|
829
|
+
"quiet" => quiet,
|
830
|
+
"rss" => rss.to_i,
|
831
|
+
"rtt_us" => rtt.to_i))
|
825
832
|
end
|
826
833
|
end
|
827
834
|
|
@@ -919,9 +926,9 @@ module Sidekiq
|
|
919
926
|
def signal(sig)
|
920
927
|
key = "#{identity}-signals"
|
921
928
|
Sidekiq.redis do |c|
|
922
|
-
c.multi do
|
923
|
-
|
924
|
-
|
929
|
+
c.multi do |transaction|
|
930
|
+
transaction.lpush(key, sig)
|
931
|
+
transaction.expire(key, 60)
|
925
932
|
end
|
926
933
|
end
|
927
934
|
end
|
@@ -955,9 +962,9 @@ module Sidekiq
|
|
955
962
|
Sidekiq.redis do |conn|
|
956
963
|
procs = conn.sscan_each("processes").to_a
|
957
964
|
procs.sort.each do |key|
|
958
|
-
valid, workers = conn.pipelined {
|
959
|
-
|
960
|
-
|
965
|
+
valid, workers = conn.pipelined { |pipeline|
|
966
|
+
pipeline.exists?(key)
|
967
|
+
pipeline.hgetall("#{key}:workers")
|
961
968
|
}
|
962
969
|
next unless valid
|
963
970
|
workers.each_pair do |tid, json|
|
@@ -985,9 +992,9 @@ module Sidekiq
|
|
985
992
|
if procs.empty?
|
986
993
|
0
|
987
994
|
else
|
988
|
-
conn.pipelined {
|
995
|
+
conn.pipelined { |pipeline|
|
989
996
|
procs.each do |key|
|
990
|
-
|
997
|
+
pipeline.hget(key, "busy")
|
991
998
|
end
|
992
999
|
}.sum(&:to_i)
|
993
1000
|
end
|