sidekiq 3.5.4 → 5.2.7

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 (175) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +61 -0
  3. data/{Contributing.md → .github/contributing.md} +0 -0
  4. data/.github/issue_template.md +11 -0
  5. data/.gitignore +3 -0
  6. data/.travis.yml +5 -10
  7. data/4.0-Upgrade.md +53 -0
  8. data/5.0-Upgrade.md +56 -0
  9. data/COMM-LICENSE +13 -11
  10. data/Changes.md +376 -1
  11. data/Ent-Changes.md +201 -2
  12. data/Gemfile +14 -18
  13. data/LICENSE +1 -1
  14. data/Pro-3.0-Upgrade.md +44 -0
  15. data/Pro-4.0-Upgrade.md +35 -0
  16. data/Pro-Changes.md +307 -2
  17. data/README.md +34 -22
  18. data/Rakefile +3 -3
  19. data/bin/sidekiq +0 -1
  20. data/bin/sidekiqctl +13 -86
  21. data/bin/sidekiqload +23 -27
  22. data/code_of_conduct.md +50 -0
  23. data/lib/generators/sidekiq/templates/worker_spec.rb.erb +3 -3
  24. data/lib/generators/sidekiq/templates/worker_test.rb.erb +6 -6
  25. data/lib/sidekiq.rb +72 -25
  26. data/lib/sidekiq/api.rb +206 -73
  27. data/lib/sidekiq/cli.rb +145 -101
  28. data/lib/sidekiq/client.rb +42 -36
  29. data/lib/sidekiq/core_ext.rb +1 -105
  30. data/lib/sidekiq/ctl.rb +221 -0
  31. data/lib/sidekiq/delay.rb +42 -0
  32. data/lib/sidekiq/exception_handler.rb +4 -5
  33. data/lib/sidekiq/extensions/action_mailer.rb +1 -0
  34. data/lib/sidekiq/extensions/active_record.rb +1 -0
  35. data/lib/sidekiq/extensions/class_methods.rb +1 -0
  36. data/lib/sidekiq/extensions/generic_proxy.rb +8 -1
  37. data/lib/sidekiq/fetch.rb +36 -111
  38. data/lib/sidekiq/job_logger.rb +25 -0
  39. data/lib/sidekiq/job_retry.rb +262 -0
  40. data/lib/sidekiq/launcher.rb +129 -55
  41. data/lib/sidekiq/logging.rb +21 -3
  42. data/lib/sidekiq/manager.rb +83 -182
  43. data/lib/sidekiq/middleware/chain.rb +1 -0
  44. data/lib/sidekiq/middleware/i18n.rb +1 -0
  45. data/lib/sidekiq/middleware/server/active_record.rb +10 -0
  46. data/lib/sidekiq/paginator.rb +1 -0
  47. data/lib/sidekiq/processor.rb +221 -103
  48. data/lib/sidekiq/rails.rb +47 -27
  49. data/lib/sidekiq/redis_connection.rb +74 -7
  50. data/lib/sidekiq/scheduled.rb +87 -28
  51. data/lib/sidekiq/testing.rb +150 -19
  52. data/lib/sidekiq/testing/inline.rb +1 -0
  53. data/lib/sidekiq/util.rb +15 -17
  54. data/lib/sidekiq/version.rb +2 -1
  55. data/lib/sidekiq/web.rb +120 -184
  56. data/lib/sidekiq/web/action.rb +89 -0
  57. data/lib/sidekiq/web/application.rb +353 -0
  58. data/lib/sidekiq/{web_helpers.rb → web/helpers.rb} +123 -47
  59. data/lib/sidekiq/web/router.rb +100 -0
  60. data/lib/sidekiq/worker.rb +135 -18
  61. data/sidekiq.gemspec +8 -14
  62. data/web/assets/images/{status-sd8051fd480.png → status.png} +0 -0
  63. data/web/assets/javascripts/application.js +24 -20
  64. data/web/assets/javascripts/dashboard.js +33 -18
  65. data/web/assets/stylesheets/application-rtl.css +246 -0
  66. data/web/assets/stylesheets/application.css +401 -7
  67. data/web/assets/stylesheets/bootstrap-rtl.min.css +9 -0
  68. data/web/assets/stylesheets/bootstrap.css +4 -8
  69. data/web/locales/ar.yml +81 -0
  70. data/web/locales/cs.yml +11 -1
  71. data/web/locales/de.yml +1 -1
  72. data/web/locales/en.yml +4 -0
  73. data/web/locales/es.yml +4 -3
  74. data/web/locales/fa.yml +80 -0
  75. data/web/locales/fr.yml +21 -12
  76. data/web/locales/he.yml +79 -0
  77. data/web/locales/ja.yml +24 -13
  78. data/web/locales/ru.yml +3 -0
  79. data/web/locales/ur.yml +80 -0
  80. data/web/views/_footer.erb +7 -9
  81. data/web/views/_job_info.erb +5 -1
  82. data/web/views/_nav.erb +5 -19
  83. data/web/views/_paging.erb +1 -1
  84. data/web/views/busy.erb +18 -9
  85. data/web/views/dashboard.erb +5 -5
  86. data/web/views/dead.erb +1 -1
  87. data/web/views/layout.erb +13 -5
  88. data/web/views/morgue.erb +16 -12
  89. data/web/views/queue.erb +12 -11
  90. data/web/views/queues.erb +5 -3
  91. data/web/views/retries.erb +19 -13
  92. data/web/views/retry.erb +2 -2
  93. data/web/views/scheduled.erb +4 -4
  94. data/web/views/scheduled_job_info.erb +1 -1
  95. metadata +45 -227
  96. data/lib/sidekiq/actor.rb +0 -39
  97. data/lib/sidekiq/middleware/server/logging.rb +0 -40
  98. data/lib/sidekiq/middleware/server/retry_jobs.rb +0 -206
  99. data/test/config.yml +0 -9
  100. data/test/env_based_config.yml +0 -11
  101. data/test/fake_env.rb +0 -0
  102. data/test/fixtures/en.yml +0 -2
  103. data/test/helper.rb +0 -49
  104. data/test/test_api.rb +0 -493
  105. data/test/test_cli.rb +0 -335
  106. data/test/test_client.rb +0 -194
  107. data/test/test_exception_handler.rb +0 -55
  108. data/test/test_extensions.rb +0 -126
  109. data/test/test_fetch.rb +0 -104
  110. data/test/test_logging.rb +0 -34
  111. data/test/test_manager.rb +0 -168
  112. data/test/test_middleware.rb +0 -159
  113. data/test/test_processor.rb +0 -237
  114. data/test/test_rails.rb +0 -21
  115. data/test/test_redis_connection.rb +0 -126
  116. data/test/test_retry.rb +0 -325
  117. data/test/test_scheduled.rb +0 -114
  118. data/test/test_scheduling.rb +0 -49
  119. data/test/test_sidekiq.rb +0 -99
  120. data/test/test_testing.rb +0 -142
  121. data/test/test_testing_fake.rb +0 -268
  122. data/test/test_testing_inline.rb +0 -93
  123. data/test/test_util.rb +0 -16
  124. data/test/test_web.rb +0 -608
  125. data/test/test_web_helpers.rb +0 -53
  126. data/web/assets/images/bootstrap/glyphicons-halflings-white.png +0 -0
  127. data/web/assets/images/bootstrap/glyphicons-halflings.png +0 -0
  128. data/web/assets/images/status/active.png +0 -0
  129. data/web/assets/images/status/idle.png +0 -0
  130. data/web/assets/javascripts/locales/README.md +0 -27
  131. data/web/assets/javascripts/locales/jquery.timeago.ar.js +0 -96
  132. data/web/assets/javascripts/locales/jquery.timeago.bg.js +0 -18
  133. data/web/assets/javascripts/locales/jquery.timeago.bs.js +0 -49
  134. data/web/assets/javascripts/locales/jquery.timeago.ca.js +0 -18
  135. data/web/assets/javascripts/locales/jquery.timeago.cs.js +0 -18
  136. data/web/assets/javascripts/locales/jquery.timeago.cy.js +0 -20
  137. data/web/assets/javascripts/locales/jquery.timeago.da.js +0 -18
  138. data/web/assets/javascripts/locales/jquery.timeago.de.js +0 -18
  139. data/web/assets/javascripts/locales/jquery.timeago.el.js +0 -18
  140. data/web/assets/javascripts/locales/jquery.timeago.en-short.js +0 -20
  141. data/web/assets/javascripts/locales/jquery.timeago.en.js +0 -20
  142. data/web/assets/javascripts/locales/jquery.timeago.es.js +0 -18
  143. data/web/assets/javascripts/locales/jquery.timeago.et.js +0 -18
  144. data/web/assets/javascripts/locales/jquery.timeago.fa.js +0 -22
  145. data/web/assets/javascripts/locales/jquery.timeago.fi.js +0 -28
  146. data/web/assets/javascripts/locales/jquery.timeago.fr-short.js +0 -16
  147. data/web/assets/javascripts/locales/jquery.timeago.fr.js +0 -17
  148. data/web/assets/javascripts/locales/jquery.timeago.he.js +0 -18
  149. data/web/assets/javascripts/locales/jquery.timeago.hr.js +0 -49
  150. data/web/assets/javascripts/locales/jquery.timeago.hu.js +0 -18
  151. data/web/assets/javascripts/locales/jquery.timeago.hy.js +0 -18
  152. data/web/assets/javascripts/locales/jquery.timeago.id.js +0 -18
  153. data/web/assets/javascripts/locales/jquery.timeago.it.js +0 -16
  154. data/web/assets/javascripts/locales/jquery.timeago.ja.js +0 -19
  155. data/web/assets/javascripts/locales/jquery.timeago.ko.js +0 -17
  156. data/web/assets/javascripts/locales/jquery.timeago.lt.js +0 -20
  157. data/web/assets/javascripts/locales/jquery.timeago.mk.js +0 -20
  158. data/web/assets/javascripts/locales/jquery.timeago.nl.js +0 -20
  159. data/web/assets/javascripts/locales/jquery.timeago.no.js +0 -18
  160. data/web/assets/javascripts/locales/jquery.timeago.pl.js +0 -31
  161. data/web/assets/javascripts/locales/jquery.timeago.pt-br.js +0 -16
  162. data/web/assets/javascripts/locales/jquery.timeago.pt.js +0 -16
  163. data/web/assets/javascripts/locales/jquery.timeago.ro.js +0 -18
  164. data/web/assets/javascripts/locales/jquery.timeago.rs.js +0 -49
  165. data/web/assets/javascripts/locales/jquery.timeago.ru.js +0 -34
  166. data/web/assets/javascripts/locales/jquery.timeago.sk.js +0 -18
  167. data/web/assets/javascripts/locales/jquery.timeago.sl.js +0 -44
  168. data/web/assets/javascripts/locales/jquery.timeago.sv.js +0 -18
  169. data/web/assets/javascripts/locales/jquery.timeago.th.js +0 -20
  170. data/web/assets/javascripts/locales/jquery.timeago.tr.js +0 -16
  171. data/web/assets/javascripts/locales/jquery.timeago.uk.js +0 -34
  172. data/web/assets/javascripts/locales/jquery.timeago.uz.js +0 -19
  173. data/web/assets/javascripts/locales/jquery.timeago.zh-cn.js +0 -20
  174. data/web/assets/javascripts/locales/jquery.timeago.zh-tw.js +0 -20
  175. data/web/views/_poll_js.erb +0 -5
data/README.md CHANGED
@@ -3,7 +3,7 @@ Sidekiq
3
3
 
4
4
  [![Gem Version](https://badge.fury.io/rb/sidekiq.svg)](https://rubygems.org/gems/sidekiq)
5
5
  [![Code Climate](https://codeclimate.com/github/mperham/sidekiq.svg)](https://codeclimate.com/github/mperham/sidekiq)
6
- [![Build Status](https://travis-ci.org/mperham/sidekiq.svg)](https://travis-ci.org/mperham/sidekiq)
6
+ [![Build Status](https://circleci.com/gh/mperham/sidekiq/tree/master.svg?style=svg)](https://circleci.com/gh/mperham/sidekiq/tree/master)
7
7
  [![Gitter Chat](https://badges.gitter.im/mperham/sidekiq.svg)](https://gitter.im/mperham/sidekiq)
8
8
 
9
9
 
@@ -11,28 +11,34 @@ Simple, efficient background processing for Ruby.
11
11
 
12
12
  Sidekiq uses threads to handle many jobs at the same time in the
13
13
  same process. It does not require Rails but will integrate tightly with
14
- Rails 3/4 to make background processing dead simple.
14
+ Rails to make background processing dead simple.
15
15
 
16
16
  Sidekiq is compatible with Resque. It uses the exact same
17
17
  message format as Resque so it can integrate into an existing Resque processing farm.
18
18
  You can have Sidekiq and Resque run side-by-side at the same time and
19
19
  use the Resque client to enqueue jobs in Redis to be processed by Sidekiq.
20
20
 
21
- At the same time, Sidekiq uses multithreading so it is much more memory efficient than
22
- Resque (which forks a new process for every job). You'll find that you might need
23
- 10 200MB resque processes to peg your CPU whereas one 300MB Sidekiq process will peg
24
- the same CPU and perform the same amount of work.
21
+ Performance
22
+ ---------------
25
23
 
24
+ Version | Latency | Garbage created for 10,000 jobs | Time to process 100,000 jobs | Throughput
25
+ -----------------|------|---------|---------|------------------------
26
+ Sidekiq 4.0.0 | 10ms | 151 MB | 22 sec | **4500 jobs/sec**
27
+ Sidekiq 3.5.1 | 22ms | 1257 MB | 125 sec | 800 jobs/sec
28
+ Resque 1.25.2 | - | - | 420 sec | 240 jobs/sec
29
+ DelayedJob 4.1.1 | - | - | 465 sec | 215 jobs/sec
30
+
31
+ <small>This benchmark can be found in `bin/sidekiqload`.</small>
26
32
 
27
33
  Requirements
28
34
  -----------------
29
35
 
30
- I test with the latest MRI (2.2, 2.1 and 2.0) and JRuby versions (1.7). Other versions/VMs
31
- are untested but might work fine. MRI 1.9 is no longer supported.
36
+ Sidekiq supports CRuby 2.2.2+ and JRuby 9k.
32
37
 
33
- All Rails releases starting from 3.2 are officially supported.
38
+ All Rails releases >= 4.0 are officially supported.
34
39
 
35
- Redis 2.4 or greater is required.
40
+ Redis 2.8 or greater is required. 3.0.3+ is recommended for large
41
+ installations with thousands of worker threads.
36
42
 
37
43
 
38
44
  Installation
@@ -45,7 +51,8 @@ Getting Started
45
51
  -----------------
46
52
 
47
53
  See the [Getting Started wiki page](https://github.com/mperham/sidekiq/wiki/Getting-Started) and follow the simple setup process.
48
- You can watch [Railscast #366](http://railscasts.com/episodes/366-sidekiq) to see Sidekiq in action. If you do everything right, you should see this:
54
+ You can watch [this Youtube playlist](https://www.youtube.com/playlist?list=PLjeHh2LSCFrWGT5uVjUuFKAcrcj5kSai1) to learn all about
55
+ Sidekiq and see its features in action. Here's the Web UI:
49
56
 
50
57
  ![Web UI](https://github.com/mperham/sidekiq/raw/master/examples/web-ui.png)
51
58
 
@@ -58,31 +65,36 @@ features, a commercial-friendly license and allow you to support high
58
65
  quality open source development all at the same time. Please see the
59
66
  [Sidekiq](http://sidekiq.org/) homepage for more detail.
60
67
 
68
+ Subscribe to the **[quarterly newsletter](https://tinyletter.com/sidekiq)** to stay informed about the latest
69
+ features and changes to Sidekiq and its bigger siblings.
70
+
61
71
 
62
- More Information
72
+ Problems?
63
73
  -----------------
64
74
 
65
- Please see the [sidekiq wiki](https://github.com/mperham/sidekiq/wiki) for the official documentation.
66
- [mperham/sidekiq on Gitter](https://gitter.im/mperham/sidekiq) is dedicated to this project,
67
- but bug reports or feature requests suggestions should still go through [issues on Github](https://github.com/mperham/sidekiq/issues). Release announcements are made to the [@sidekiq](https://twitter.com/sidekiq) Twitter account.
75
+ **Please do not directly email any Sidekiq committers with questions or problems.** A community is best served when discussions are held in public.
68
76
 
69
- You may also find useful a [Google Group](https://groups.google.com/forum/#!forum/sidekiq) dedicated to Sidekiq discussion and [a Sidekiq tag](https://stackoverflow.com/questions/tagged/sidekiq) on Stack Overflow.
77
+ 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.
78
+ Searching the [issues](https://github.com/mperham/sidekiq/issues) for your problem is also a good idea.
70
79
 
80
+ Sidekiq Pro and Sidekiq Enterprise customers get private email support. You can purchase at http://sidekiq.org; email support@contribsys.com for help.
71
81
 
72
- Problems?
73
- -----------------
82
+ Useful resources:
74
83
 
75
- **Please do not directly email any Sidekiq committers with questions or problems.** A community is best served when discussions are held in public.
84
+ * Product documentation is in the [wiki](https://github.com/mperham/sidekiq/wiki).
85
+ * Release announcements are made to the [@sidekiq](https://twitter.com/sidekiq) Twitter account.
86
+ * The [Sidekiq tag](https://stackoverflow.com/questions/tagged/sidekiq) on Stack Overflow has lots of useful Q &amp; A.
76
87
 
77
- 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. Searching the issues for your problem is also a good idea. If that doesn't help, feel free to email the Sidekiq mailing list, chat in Gitter, or open a new issue.
78
- The mailing list is the preferred place to ask questions on usage. If you are encountering what you think is a bug, please open an issue.
88
+ **No support via Twitter**
79
89
 
90
+ Every Friday morning is Sidekiq happy hour: I video chat and answer questions.
91
+ See the [Sidekiq support page](http://sidekiq.org/support.html) for details.
80
92
 
81
93
  Thanks
82
94
  -----------------
83
95
 
84
96
  Sidekiq stays fast by using the [JProfiler java profiler](http://www.ej-technologies.com/products/jprofiler/overview.html) to find and fix
85
- performance problems on JRuby. Unfortunately MRI does not have good profile tooling.
97
+ performance problems on JRuby. Unfortunately MRI does not have good multithreaded profiling tools.
86
98
 
87
99
 
88
100
  License
data/Rakefile CHANGED
@@ -1,9 +1,9 @@
1
1
  require 'bundler/gem_tasks'
2
2
  require 'rake/testtask'
3
+
3
4
  Rake::TestTask.new(:test) do |test|
4
- #SO MUCH NOISE
5
- #test.warning = true
5
+ test.warning = true
6
6
  test.pattern = 'test/**/test_*.rb'
7
7
  end
8
8
 
9
- task :default => :test
9
+ task default: :test
@@ -3,7 +3,6 @@
3
3
  # Quiet some warnings we see when running in warning mode:
4
4
  # RUBYOPT=-w bundle exec sidekiq
5
5
  $TESTING = false
6
- $CELLULOID_DEBUG = false
7
6
 
8
7
  require_relative '../lib/sidekiq/cli'
9
8
 
@@ -1,93 +1,20 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'fileutils'
4
+ require 'sidekiq/api'
5
+ require 'sidekiq/ctl'
4
6
 
5
- class Sidekiqctl
6
- DEFAULT_KILL_TIMEOUT = 10
7
-
8
- attr_reader :stage, :pidfile, :kill_timeout
9
-
10
- def self.print_usage
11
- puts "#{File.basename($0)} - stop a Sidekiq process from the command line."
12
- puts
13
- puts "Usage: #{File.basename($0)} <command> <pidfile> <kill_timeout>"
14
- puts " where <command> is either 'quiet' or 'stop'"
15
- puts " <pidfile> is path to a pidfile"
16
- puts " <kill_timeout> is number of seconds to wait until Sidekiq exits"
17
- puts " (default: #{Sidekiqctl::DEFAULT_KILL_TIMEOUT}), after which Sidekiq will be KILL'd"
18
- puts
19
- puts "Be sure to set the kill_timeout LONGER than Sidekiq's -t timeout. If you want"
20
- puts "to wait 60 seconds for jobs to finish, use `sidekiq -t 60` and `sidekiqctl stop"
21
- puts " path_to_pidfile 61`"
22
- puts
23
- end
24
-
25
- def initialize(stage, pidfile, timeout)
26
- @stage = stage
27
- @pidfile = pidfile
28
- @kill_timeout = timeout
29
-
30
- done('No pidfile given', :error) if !pidfile
31
- done("Pidfile #{pidfile} does not exist", :warn) if !File.exist?(pidfile)
32
- done('Invalid pidfile content', :error) if pid == 0
33
-
34
- fetch_process
35
-
36
- begin
37
- send(stage)
38
- rescue NoMethodError
39
- done "Invalid command: #{stage}", :error
40
- end
41
- end
42
-
43
- def fetch_process
44
- Process.getpgid(pid)
45
- rescue Errno::ESRCH
46
- done "Process doesn't exist", :error
47
- end
48
-
49
- def done(msg, error = nil)
50
- puts msg
51
- exit(exit_signal(error))
52
- end
53
-
54
- def exit_signal(error)
55
- (error == :error) ? 1 : 0
56
- end
57
-
58
- def pid
59
- @pid ||= File.read(pidfile).to_i
60
- end
61
-
62
- def quiet
63
- `kill -USR1 #{pid}`
64
- end
65
-
66
- def stop
67
- `kill -TERM #{pid}`
68
- kill_timeout.times do
69
- begin
70
- Process.getpgid(pid)
71
- rescue Errno::ESRCH
72
- FileUtils.rm_f pidfile
73
- done 'Sidekiq shut down gracefully.'
74
- end
75
- sleep 1
76
- end
77
- `kill -9 #{pid}`
78
- FileUtils.rm_f pidfile
79
- done 'Sidekiq shut down forcefully.'
80
- end
81
- alias_method :shutdown, :stop
82
- end
83
-
84
- if ARGV.length < 2
85
- Sidekiqctl.print_usage
7
+ if ARGV[0] == 'status'
8
+ Sidekiq::Ctl::Status.new.display(ARGV[1])
86
9
  else
87
- stage = ARGV[0]
88
- pidfile = ARGV[1]
89
- timeout = ARGV[2].to_i
90
- timeout = Sidekiqctl::DEFAULT_KILL_TIMEOUT if timeout == 0
10
+ if ARGV.length < 2
11
+ Sidekiq::Ctl.print_usage
12
+ else
13
+ stage = ARGV[0]
14
+ pidfile = ARGV[1]
15
+ timeout = ARGV[2].to_i
16
+ timeout = Sidekiq::Ctl::DEFAULT_KILL_TIMEOUT if timeout == 0
91
17
 
92
- Sidekiqctl.new(stage, pidfile, timeout)
18
+ Sidekiq::Ctl.new(stage, pidfile, timeout)
19
+ end
93
20
  end
@@ -3,21 +3,22 @@
3
3
  # Quiet some warnings we see when running in warning mode:
4
4
  # RUBYOPT=-w bundle exec sidekiq
5
5
  $TESTING = false
6
- $CELLULOID_DEBUG = false
7
6
 
8
- require 'celluloid/current'
9
- puts Celluloid::VERSION
7
+ #require 'ruby-prof'
8
+ Bundler.require(:default)
9
+
10
10
  require_relative '../lib/sidekiq/cli'
11
11
  require_relative '../lib/sidekiq/launcher'
12
- Celluloid.logger = nil
13
12
 
14
13
  include Sidekiq::Util
15
14
 
16
15
  Sidekiq.configure_server do |config|
17
- config.redis = { db: 13, port: 6380 }
16
+ #config.options[:concurrency] = 1
17
+ config.redis = { db: 13 }
18
18
  config.options[:queues] << 'default'
19
19
  config.logger.level = Logger::ERROR
20
20
  config.average_scheduled_poll_interval = 2
21
+ config.reliable! if defined?(Sidekiq::Pro)
21
22
  end
22
23
 
23
24
  class LoadWorker
@@ -35,17 +36,17 @@ end
35
36
  # brew tap shopify/shopify
36
37
  # brew install toxiproxy
37
38
  # gem install toxiproxy
38
- require 'toxiproxy'
39
+ #require 'toxiproxy'
39
40
  # simulate a non-localhost network for realer-world conditions.
40
41
  # adding 1ms of network latency has an ENORMOUS impact on benchmarks
41
- Toxiproxy.populate([{
42
- "name": "redis",
43
- "listen": "127.0.0.1:6380",
44
- "upstream": "127.0.0.1:6379"
45
- }])
42
+ #Toxiproxy.populate([{
43
+ #"name": "redis",
44
+ #"listen": "127.0.0.1:6380",
45
+ #"upstream": "127.0.0.1:6379"
46
+ #}])
46
47
 
47
48
  self_read, self_write = IO.pipe
48
- %w(INT TERM USR1 USR2 TTIN).each do |sig|
49
+ %w(INT TERM TSTP TTIN).each do |sig|
49
50
  begin
50
51
  trap sig do
51
52
  self_write.puts(sig)
@@ -64,20 +65,14 @@ def handle_signal(launcher, sig)
64
65
  # http://jira.codehaus.org/browse/JRUBY-4637
65
66
  raise Interrupt
66
67
  when 'TERM'
67
- # Heroku sends TERM and then waits 10 seconds for process to exit.
68
+ # Heroku sends TERM and then waits 30 seconds for process to exit.
68
69
  raise Interrupt
69
- when 'USR1'
70
- Sidekiq.logger.info "Received USR1, no longer accepting new work"
71
- launcher.manager.async.stop
72
- #fire_event(:quiet, true)
73
- when 'USR2'
74
- if Sidekiq.options[:logfile]
75
- Sidekiq.logger.info "Received USR2, reopening log file"
76
- Sidekiq::Logging.reopen_logs
77
- end
70
+ when 'TSTP'
71
+ Sidekiq.logger.info "Received TSTP, no longer accepting new work"
72
+ launcher.quiet
78
73
  when 'TTIN'
79
74
  Thread.list.each do |thread|
80
- Sidekiq.logger.warn "Thread TID-#{thread.object_id.to_s(36)} #{thread['label']}"
75
+ Sidekiq.logger.warn "Thread TID-#{(thread.object_id ^ ::Process.pid).to_s(36)} #{thread['label']}"
81
76
  if thread.backtrace
82
77
  Sidekiq.logger.warn thread.backtrace.join("\n")
83
78
  else
@@ -108,7 +103,7 @@ Sidekiq.logger.error "Created #{count*iter} jobs"
108
103
  Monitoring = Thread.new do
109
104
  watchdog("monitor thread") do
110
105
  while true
111
- sleep 2
106
+ sleep 1
112
107
  qsize, retries = Sidekiq.redis do |conn|
113
108
  conn.pipelined do
114
109
  conn.llen "queue:default"
@@ -129,8 +124,9 @@ end
129
124
  begin
130
125
  #RubyProf::exclude_threads = [ Monitoring ]
131
126
  #RubyProf.start
132
- Sidekiq.logger.error "Simulating 1ms of latency between Sidekiq and redis"
133
- Toxiproxy[:redis].downstream(:latency, latency: 1).apply do
127
+ fire_event(:startup)
128
+ #Sidekiq.logger.error "Simulating 1ms of latency between Sidekiq and redis"
129
+ #Toxiproxy[:redis].downstream(:latency, latency: 1).apply do
134
130
  launcher = Sidekiq::Launcher.new(Sidekiq.options)
135
131
  launcher.run
136
132
 
@@ -138,7 +134,7 @@ begin
138
134
  signal = readable_io.first[0].gets.strip
139
135
  handle_signal(launcher, signal)
140
136
  end
141
- end
137
+ #end
142
138
  rescue SystemExit => e
143
139
  #Sidekiq.logger.error("Profiling...")
144
140
  #result = RubyProf.stop
@@ -0,0 +1,50 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This Code of Conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting the project maintainer at mperham AT gmail.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+
45
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
46
+ version 1.3.0, available at
47
+ [http://contributor-covenant.org/version/1/3/0/][version]
48
+
49
+ [homepage]: http://contributor-covenant.org
50
+ [version]: http://contributor-covenant.org/version/1/3/0/
@@ -1,6 +1,6 @@
1
1
  require 'rails_helper'
2
2
  <% module_namespacing do -%>
3
- RSpec.describe <%= class_name %>Worker, :type => :worker do
4
- pending "add some examples to (or delete) #{__FILE__}"
3
+ RSpec.describe <%= class_name %>Worker, type: :worker do
4
+ pending "add some examples to (or delete) #{__FILE__}"
5
5
  end
6
- <% end -%>
6
+ <% end -%>
@@ -1,8 +1,8 @@
1
- require_relative 'test_helper'
1
+ require 'test_helper'
2
2
  <% module_namespacing do -%>
3
- class <%= class_name %>WorkerTest < MiniTest::Unit::TestCase
4
- def test_example
5
- skip "add some examples to (or delete) #{__FILE__}"
6
- end
3
+ class <%= class_name %>WorkerTest < <% if defined? Minitest::Test %>Minitest::Test<% else %>MiniTest::Unit::TestCase<% end %>
4
+ def test_example
5
+ skip "add some examples to (or delete) #{__FILE__}"
6
+ end
7
7
  end
8
- <% end -%>
8
+ <% end -%>
@@ -1,11 +1,13 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  require 'sidekiq/version'
3
- fail "Sidekiq #{Sidekiq::VERSION} does not support Ruby 1.9." if RUBY_PLATFORM != 'java' && RUBY_VERSION < '2.0.0'
4
+ fail "Sidekiq #{Sidekiq::VERSION} does not support Ruby versions below 2.2.2." if RUBY_PLATFORM != 'java' && Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2.2')
4
5
 
5
6
  require 'sidekiq/logging'
6
7
  require 'sidekiq/client'
7
8
  require 'sidekiq/worker'
8
9
  require 'sidekiq/redis_connection'
10
+ require 'sidekiq/delay'
9
11
 
10
12
  require 'json'
11
13
 
@@ -16,20 +18,23 @@ module Sidekiq
16
18
  DEFAULTS = {
17
19
  queues: [],
18
20
  labels: [],
19
- concurrency: 25,
21
+ concurrency: 10,
20
22
  require: '.',
21
23
  environment: nil,
22
24
  timeout: 8,
23
25
  poll_interval_average: nil,
24
- average_scheduled_poll_interval: 15,
26
+ average_scheduled_poll_interval: 5,
25
27
  error_handlers: [],
28
+ death_handlers: [],
26
29
  lifecycle_events: {
27
30
  startup: [],
28
31
  quiet: [],
29
32
  shutdown: [],
33
+ heartbeat: [],
30
34
  },
31
35
  dead_max_jobs: 10_000,
32
- dead_timeout_in_seconds: 180 * 24 * 60 * 60 # 6 months
36
+ dead_timeout_in_seconds: 180 * 24 * 60 * 60, # 6 months
37
+ reloader: proc { |&block| block.call },
33
38
  }
34
39
 
35
40
  DEFAULT_WORKER_OPTIONS = {
@@ -37,6 +42,14 @@ module Sidekiq
37
42
  'queue' => 'default'
38
43
  }
39
44
 
45
+ FAKE_INFO = {
46
+ "redis_version" => "9.9.9",
47
+ "uptime_in_days" => "9999",
48
+ "connected_clients" => "9999",
49
+ "used_memory_human" => "9P",
50
+ "used_memory_peak_human" => "9P"
51
+ }
52
+
40
53
  def self.❨╯°□°❩╯︵┻━┻
41
54
  puts "Calm down, yo."
42
55
  end
@@ -83,14 +96,32 @@ module Sidekiq
83
96
  begin
84
97
  yield conn
85
98
  rescue Redis::CommandError => ex
86
- #2550 Failover can cause the server to become a slave, need
87
- # to disconnect and reopen the socket to get back to the master.
99
+ #2550 Failover can cause the server to become a replica, need
100
+ # to disconnect and reopen the socket to get back to the primary.
88
101
  (conn.disconnect!; retryable = false; retry) if retryable && ex.message =~ /READONLY/
89
102
  raise
90
103
  end
91
104
  end
92
105
  end
93
106
 
107
+ def self.redis_info
108
+ redis do |conn|
109
+ begin
110
+ # admin commands can't go through redis-namespace starting
111
+ # in redis-namespace 2.0
112
+ if conn.respond_to?(:namespace)
113
+ conn.redis.info
114
+ else
115
+ conn.info
116
+ end
117
+ rescue Redis::CommandError => ex
118
+ #2850 return fake version when INFO command has (probably) been renamed
119
+ raise unless ex.message =~ /unknown command/
120
+ FAKE_INFO
121
+ end
122
+ end
123
+ end
124
+
94
125
  def self.redis_pool
95
126
  @redis ||= Sidekiq::RedisConnection.create
96
127
  end
@@ -110,23 +141,45 @@ module Sidekiq
110
141
  end
111
142
 
112
143
  def self.server_middleware
113
- @server_chain ||= Processor.default_middleware
144
+ @server_chain ||= default_server_middleware
114
145
  yield @server_chain if block_given?
115
146
  @server_chain
116
147
  end
117
148
 
118
- def self.default_worker_options=(hash)
119
- @default_worker_options = default_worker_options.merge(hash.stringify_keys)
149
+ def self.default_server_middleware
150
+ Middleware::Chain.new
120
151
  end
121
152
 
153
+ def self.default_worker_options=(hash)
154
+ # stringify
155
+ @default_worker_options = default_worker_options.merge(Hash[hash.map{|k, v| [k.to_s, v]}])
156
+ end
122
157
  def self.default_worker_options
123
158
  defined?(@default_worker_options) ? @default_worker_options : DEFAULT_WORKER_OPTIONS
124
159
  end
125
160
 
161
+ def self.default_retries_exhausted=(prok)
162
+ logger.info { "default_retries_exhausted is deprecated, please use `config.death_handlers << -> {|job, ex| }`" }
163
+ return nil unless prok
164
+ death_handlers << prok
165
+ end
166
+
167
+ ##
168
+ # Death handlers are called when all retries for a job have been exhausted and
169
+ # the job dies. It's the notification to your application
170
+ # that this job will not succeed without manual intervention.
171
+ #
172
+ # Sidekiq.configure_server do |config|
173
+ # config.death_handlers << ->(job, ex) do
174
+ # end
175
+ # end
176
+ def self.death_handlers
177
+ options[:death_handlers]
178
+ end
179
+
126
180
  def self.load_json(string)
127
181
  JSON.parse(string)
128
182
  end
129
-
130
183
  def self.dump_json(object)
131
184
  JSON.generate(object)
132
185
  end
@@ -134,21 +187,10 @@ module Sidekiq
134
187
  def self.logger
135
188
  Sidekiq::Logging.logger
136
189
  end
137
-
138
190
  def self.logger=(log)
139
191
  Sidekiq::Logging.logger = log
140
192
  end
141
193
 
142
- # When set, overrides Sidekiq.options[:average_scheduled_poll_interval] and sets
143
- # the average interval that this process will delay before checking for
144
- # scheduled jobs or job retries that are ready to run.
145
- #
146
- # See sidekiq/scheduled.rb for an in-depth explanation of this value
147
- def self.poll_interval=(interval)
148
- $stderr.puts "DEPRECATION: `config.poll_interval = #{interval}` will be removed in Sidekiq 4. Please update to `config.average_scheduled_poll_interval = #{interval}`."
149
- self.options[:poll_interval_average] = interval
150
- end
151
-
152
194
  # How frequently Redis should be checked by a random Sidekiq process for
153
195
  # scheduled and retriable jobs. Each individual process will take turns by
154
196
  # waiting some multiple of this value.
@@ -182,9 +224,14 @@ module Sidekiq
182
224
  raise ArgumentError, "Invalid event name: #{event}" unless options[:lifecycle_events].key?(event)
183
225
  options[:lifecycle_events][event] << block
184
226
  end
227
+
228
+ # We are shutting down Sidekiq but what about workers that
229
+ # are working on some long job? This error is
230
+ # raised in workers that have not finished within the hard
231
+ # timeout limit. This is needed to rollback db transactions,
232
+ # otherwise Ruby's Thread#kill will commit. See #377.
233
+ # DO NOT RESCUE THIS ERROR IN YOUR WORKERS
234
+ class Shutdown < Interrupt; end
185
235
  end
186
236
 
187
- require 'sidekiq/extensions/class_methods'
188
- require 'sidekiq/extensions/action_mailer'
189
- require 'sidekiq/extensions/active_record'
190
237
  require 'sidekiq/rails' if defined?(::Rails::Engine)