sidekiq 6.0.4 → 7.0.2

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.

Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +336 -6
  3. data/LICENSE.txt +9 -0
  4. data/README.md +22 -20
  5. data/bin/sidekiq +22 -3
  6. data/bin/sidekiqload +71 -76
  7. data/bin/sidekiqmon +1 -1
  8. data/lib/generators/sidekiq/job_generator.rb +57 -0
  9. data/lib/generators/sidekiq/templates/{worker.rb.erb → job.rb.erb} +2 -2
  10. data/lib/generators/sidekiq/templates/{worker_spec.rb.erb → job_spec.rb.erb} +1 -1
  11. data/lib/generators/sidekiq/templates/{worker_test.rb.erb → job_test.rb.erb} +1 -1
  12. data/lib/sidekiq/api.rb +365 -230
  13. data/lib/sidekiq/capsule.rb +110 -0
  14. data/lib/sidekiq/cli.rb +120 -86
  15. data/lib/sidekiq/client.rb +81 -85
  16. data/lib/sidekiq/{util.rb → component.rb} +13 -14
  17. data/lib/sidekiq/config.rb +270 -0
  18. data/lib/sidekiq/deploy.rb +62 -0
  19. data/lib/sidekiq/embedded.rb +61 -0
  20. data/lib/sidekiq/fetch.rb +42 -32
  21. data/lib/sidekiq/{worker.rb → job.rb} +165 -34
  22. data/lib/sidekiq/job_logger.rb +18 -30
  23. data/lib/sidekiq/job_retry.rb +80 -60
  24. data/lib/sidekiq/job_util.rb +71 -0
  25. data/lib/sidekiq/launcher.rb +173 -85
  26. data/lib/sidekiq/logger.rb +13 -47
  27. data/lib/sidekiq/manager.rb +40 -41
  28. data/lib/sidekiq/metrics/query.rb +153 -0
  29. data/lib/sidekiq/metrics/shared.rb +95 -0
  30. data/lib/sidekiq/metrics/tracking.rb +134 -0
  31. data/lib/sidekiq/middleware/chain.rb +90 -46
  32. data/lib/sidekiq/middleware/current_attributes.rb +58 -0
  33. data/lib/sidekiq/middleware/i18n.rb +6 -4
  34. data/lib/sidekiq/middleware/modules.rb +21 -0
  35. data/lib/sidekiq/monitor.rb +19 -4
  36. data/lib/sidekiq/paginator.rb +17 -9
  37. data/lib/sidekiq/processor.rb +57 -60
  38. data/lib/sidekiq/rails.rb +33 -23
  39. data/lib/sidekiq/redis_client_adapter.rb +115 -0
  40. data/lib/sidekiq/redis_connection.rb +21 -87
  41. data/lib/sidekiq/ring_buffer.rb +29 -0
  42. data/lib/sidekiq/scheduled.rb +102 -39
  43. data/lib/sidekiq/sd_notify.rb +149 -0
  44. data/lib/sidekiq/systemd.rb +24 -0
  45. data/lib/sidekiq/testing/inline.rb +4 -4
  46. data/lib/sidekiq/testing.rb +43 -72
  47. data/lib/sidekiq/transaction_aware_client.rb +44 -0
  48. data/lib/sidekiq/version.rb +2 -1
  49. data/lib/sidekiq/web/action.rb +3 -3
  50. data/lib/sidekiq/web/application.rb +47 -24
  51. data/lib/sidekiq/web/csrf_protection.rb +180 -0
  52. data/lib/sidekiq/web/helpers.rb +59 -47
  53. data/lib/sidekiq/web/router.rb +6 -5
  54. data/lib/sidekiq/web.rb +31 -74
  55. data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
  56. data/lib/sidekiq.rb +86 -199
  57. data/sidekiq.gemspec +36 -7
  58. data/web/assets/images/apple-touch-icon.png +0 -0
  59. data/web/assets/javascripts/application.js +130 -61
  60. data/web/assets/javascripts/base-charts.js +106 -0
  61. data/web/assets/javascripts/chart.min.js +13 -0
  62. data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
  63. data/web/assets/javascripts/dashboard-charts.js +166 -0
  64. data/web/assets/javascripts/dashboard.js +36 -273
  65. data/web/assets/javascripts/metrics.js +236 -0
  66. data/web/assets/stylesheets/application-dark.css +146 -124
  67. data/web/assets/stylesheets/application-rtl.css +2 -95
  68. data/web/assets/stylesheets/application.css +100 -529
  69. data/web/locales/ar.yml +71 -65
  70. data/web/locales/cs.yml +62 -62
  71. data/web/locales/da.yml +52 -52
  72. data/web/locales/de.yml +65 -65
  73. data/web/locales/el.yml +43 -24
  74. data/web/locales/en.yml +83 -67
  75. data/web/locales/es.yml +70 -54
  76. data/web/locales/fa.yml +65 -65
  77. data/web/locales/fr.yml +69 -62
  78. data/web/locales/he.yml +65 -64
  79. data/web/locales/hi.yml +59 -59
  80. data/web/locales/it.yml +53 -53
  81. data/web/locales/ja.yml +73 -65
  82. data/web/locales/ko.yml +52 -52
  83. data/web/locales/lt.yml +83 -0
  84. data/web/locales/nb.yml +61 -61
  85. data/web/locales/nl.yml +52 -52
  86. data/web/locales/pl.yml +45 -45
  87. data/web/locales/pt-br.yml +63 -55
  88. data/web/locales/pt.yml +51 -51
  89. data/web/locales/ru.yml +68 -63
  90. data/web/locales/sv.yml +53 -53
  91. data/web/locales/ta.yml +60 -60
  92. data/web/locales/uk.yml +62 -61
  93. data/web/locales/ur.yml +64 -64
  94. data/web/locales/vi.yml +83 -0
  95. data/web/locales/zh-cn.yml +43 -16
  96. data/web/locales/zh-tw.yml +42 -8
  97. data/web/views/_footer.erb +6 -3
  98. data/web/views/_job_info.erb +17 -1
  99. data/web/views/_nav.erb +1 -1
  100. data/web/views/_poll_link.erb +3 -6
  101. data/web/views/_summary.erb +7 -7
  102. data/web/views/busy.erb +70 -21
  103. data/web/views/dashboard.erb +58 -18
  104. data/web/views/dead.erb +1 -1
  105. data/web/views/layout.erb +3 -2
  106. data/web/views/metrics.erb +80 -0
  107. data/web/views/metrics_for_job.erb +69 -0
  108. data/web/views/morgue.erb +7 -7
  109. data/web/views/queue.erb +15 -11
  110. data/web/views/queues.erb +4 -4
  111. data/web/views/retries.erb +8 -8
  112. data/web/views/retry.erb +1 -1
  113. data/web/views/scheduled.erb +2 -2
  114. metadata +79 -55
  115. data/.circleci/config.yml +0 -82
  116. data/.github/contributing.md +0 -32
  117. data/.github/issue_template.md +0 -11
  118. data/.gitignore +0 -13
  119. data/.standard.yml +0 -20
  120. data/3.0-Upgrade.md +0 -70
  121. data/4.0-Upgrade.md +0 -53
  122. data/5.0-Upgrade.md +0 -56
  123. data/6.0-Upgrade.md +0 -72
  124. data/COMM-LICENSE +0 -97
  125. data/Ent-2.0-Upgrade.md +0 -37
  126. data/Ent-Changes.md +0 -256
  127. data/Gemfile +0 -24
  128. data/Gemfile.lock +0 -199
  129. data/LICENSE +0 -9
  130. data/Pro-2.0-Upgrade.md +0 -138
  131. data/Pro-3.0-Upgrade.md +0 -44
  132. data/Pro-4.0-Upgrade.md +0 -35
  133. data/Pro-5.0-Upgrade.md +0 -25
  134. data/Pro-Changes.md +0 -776
  135. data/Rakefile +0 -10
  136. data/code_of_conduct.md +0 -50
  137. data/lib/generators/sidekiq/worker_generator.rb +0 -57
  138. data/lib/sidekiq/delay.rb +0 -41
  139. data/lib/sidekiq/exception_handler.rb +0 -27
  140. data/lib/sidekiq/extensions/action_mailer.rb +0 -47
  141. data/lib/sidekiq/extensions/active_record.rb +0 -42
  142. data/lib/sidekiq/extensions/class_methods.rb +0 -42
  143. data/lib/sidekiq/extensions/generic_proxy.rb +0 -31
data/bin/sidekiqload CHANGED
@@ -4,78 +4,71 @@
4
4
  # RUBYOPT=-w bundle exec sidekiq
5
5
  $TESTING = false
6
6
 
7
- #require 'ruby-prof'
8
- require 'bundler/setup'
7
+ # require "ruby-prof"
8
+ require "bundler/setup"
9
9
  Bundler.require(:default, :load_test)
10
10
 
11
- require_relative '../lib/sidekiq/cli'
12
- require_relative '../lib/sidekiq/launcher'
13
-
14
- include Sidekiq::Util
15
-
16
- Sidekiq.configure_server do |config|
17
- config.options[:concurrency] = 10
18
- config.redis = { db: 13, port: 6380, driver: :hiredis }
19
- config.options[:queues] << 'default'
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]
20
16
  config.logger.level = Logger::ERROR
21
17
  config.average_scheduled_poll_interval = 2
22
18
  config.reliable! if defined?(Sidekiq::Pro)
23
19
  end
24
20
 
25
21
  class LoadWorker
26
- include Sidekiq::Worker
22
+ include Sidekiq::Job
27
23
  sidekiq_options retry: 1
28
24
  sidekiq_retry_in do |x|
29
25
  1
30
26
  end
31
27
 
32
- def perform(idx, ts=nil)
33
- puts(Time.now.to_f - ts) if ts != nil
34
- #raise idx.to_s if idx % 100 == 1
28
+ def perform(idx, ts = nil)
29
+ puts(Time.now.to_f - ts) if !ts.nil?
30
+ # raise idx.to_s if idx % 100 == 1
35
31
  end
36
32
  end
37
33
 
38
34
  # brew tap shopify/shopify
39
35
  # brew install toxiproxy
40
- # gem install toxiproxy
41
36
  # run `toxiproxy-server` in a separate terminal window.
42
- require 'toxiproxy'
37
+ require "toxiproxy"
43
38
  # simulate a non-localhost network for realer-world conditions.
44
39
  # adding 1ms of network latency has an ENORMOUS impact on benchmarks
45
40
  Toxiproxy.populate([{
46
- "name": "redis",
47
- "listen": "127.0.0.1:6380",
48
- "upstream": "127.0.0.1:6379"
41
+ name: "redis",
42
+ listen: "127.0.0.1:6380",
43
+ upstream: "127.0.0.1:6379"
49
44
  }])
50
45
 
51
46
  self_read, self_write = IO.pipe
52
- %w(INT TERM TSTP TTIN).each do |sig|
53
- begin
54
- trap sig do
55
- self_write.puts(sig)
56
- end
57
- rescue ArgumentError
58
- puts "Signal #{sig} not supported"
47
+ %w[INT TERM TSTP TTIN].each do |sig|
48
+ trap sig do
49
+ self_write.puts(sig)
59
50
  end
51
+ rescue ArgumentError
52
+ puts "Signal #{sig} not supported"
60
53
  end
61
54
 
62
- Sidekiq.redis {|c| c.flushdb}
55
+ Sidekiq.redis { |c| c.flushdb }
63
56
  def handle_signal(launcher, sig)
64
57
  Sidekiq.logger.debug "Got #{sig} signal"
65
58
  case sig
66
- when 'INT'
59
+ when "INT"
67
60
  # Handle Ctrl-C in JRuby like MRI
68
61
  # http://jira.codehaus.org/browse/JRUBY-4637
69
62
  raise Interrupt
70
- when 'TERM'
63
+ when "TERM"
71
64
  # Heroku sends TERM and then waits 30 seconds for process to exit.
72
65
  raise Interrupt
73
- when 'TSTP'
66
+ when "TSTP"
74
67
  Sidekiq.logger.info "Received TSTP, no longer accepting new work"
75
68
  launcher.quiet
76
- when 'TTIN'
69
+ when "TTIN"
77
70
  Thread.list.each do |thread|
78
- Sidekiq.logger.warn "Thread TID-#{(thread.object_id ^ ::Process.pid).to_s(36)} #{thread['label']}"
71
+ Sidekiq.logger.warn "Thread TID-#{(thread.object_id ^ ::Process.pid).to_s(36)} #{thread["label"]}"
79
72
  if thread.backtrace
80
73
  Sidekiq.logger.warn thread.backtrace.join("\n")
81
74
  else
@@ -93,65 +86,67 @@ iter = 10
93
86
  count = 10_000
94
87
 
95
88
  iter.times do
96
- arr = Array.new(count) do
97
- []
98
- end
99
- count.times do |idx|
100
- arr[idx][0] = idx
101
- end
102
- Sidekiq::Client.push_bulk('class' => LoadWorker, 'args' => arr)
89
+ arr = Array.new(count) { |idx| [idx] }
90
+ Sidekiq::Client.push_bulk("class" => LoadWorker, "args" => arr)
103
91
  end
104
- Sidekiq.logger.error "Created #{count*iter} jobs"
92
+ Sidekiq.logger.error "Created #{count * iter} jobs"
105
93
 
106
94
  start = Time.now
107
95
 
108
96
  Monitoring = Thread.new do
109
- watchdog("monitor thread") do
110
- while true
97
+ loop do
98
+ sleep 1.0
99
+ qsize = Sidekiq.redis do |conn|
100
+ conn.llen "queue:default"
101
+ 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
+
111
112
  sleep 0.2
112
- qsize = Sidekiq.redis do |conn|
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
113
+ exit(0)
128
114
  end
129
115
  end
130
116
  end
131
117
 
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
124
+ end
125
+ end
126
+
132
127
  begin
133
- #RubyProf::exclude_threads = [ Monitoring ]
134
- #RubyProf.start
135
- fire_event(:startup)
136
- Sidekiq.logger.error "Simulating 1ms of latency between Sidekiq and redis"
137
- Toxiproxy[:redis].downstream(:latency, latency: 1).apply do
138
- launcher = Sidekiq::Launcher.new(Sidekiq.options)
139
- launcher.run
140
-
141
- while readable_io = IO.select([self_read])
128
+ # RubyProf.exclude_threads = [Monitoring]
129
+ # RubyProf.start
130
+
131
+ with_latency(Integer(ENV.fetch("LATENCY", "1"))) do
132
+ x.run
133
+
134
+ while (readable_io = IO.select([self_read]))
142
135
  signal = readable_io.first[0].gets.strip
143
- handle_signal(launcher, signal)
136
+ handle_signal(x, signal)
144
137
  end
145
138
  end
146
- 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)
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)
151
144
  # normal
152
145
  rescue => e
153
146
  raise e if $DEBUG
154
- STDERR.puts e.message
155
- STDERR.puts e.backtrace.join("\n")
147
+ warn e.message
148
+ warn e.backtrace.join("\n")
156
149
  exit 1
150
+ ensure
151
+ x.stop
157
152
  end
data/bin/sidekiqmon CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'sidekiq/monitor'
3
+ require "sidekiq/monitor"
4
4
 
5
5
  section = "all"
6
6
  section = ARGV[0] if ARGV.size == 1
@@ -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
@@ -1,6 +1,6 @@
1
1
  <% module_namespacing do -%>
2
- class <%= class_name %>Worker
3
- include Sidekiq::Worker
2
+ class <%= class_name %>Job
3
+ include Sidekiq::Job
4
4
 
5
5
  def perform(*args)
6
6
  # Do something
@@ -1,6 +1,6 @@
1
1
  require 'rails_helper'
2
2
  <% module_namespacing do -%>
3
- RSpec.describe <%= class_name %>Worker, type: :worker do
3
+ RSpec.describe <%= class_name %>Job, type: :job do
4
4
  pending "add some examples to (or delete) #{__FILE__}"
5
5
  end
6
6
  <% end -%>
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
  <% module_namespacing do -%>
3
- class <%= class_name %>WorkerTest < Minitest::Test
3
+ class <%= class_name %>JobTest < Minitest::Test
4
4
  def test_example
5
5
  skip "add some examples to (or delete) #{__FILE__}"
6
6
  end