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
@@ -1,55 +0,0 @@
1
- require_relative 'helper'
2
- require 'sidekiq/exception_handler'
3
- require 'stringio'
4
- require 'logger'
5
-
6
- ExceptionHandlerTestException = Class.new(StandardError)
7
- TEST_EXCEPTION = ExceptionHandlerTestException.new("Something didn't work!")
8
-
9
- class Component
10
- include Sidekiq::ExceptionHandler
11
-
12
- def invoke_exception(args)
13
- raise TEST_EXCEPTION
14
- rescue ExceptionHandlerTestException => e
15
- handle_exception(e,args)
16
- end
17
- end
18
-
19
- class TestExceptionHandler < Sidekiq::Test
20
- describe "with mock logger" do
21
- before do
22
- @old_logger = Sidekiq.logger
23
- @str_logger = StringIO.new
24
- Sidekiq.logger = Logger.new(@str_logger)
25
- end
26
-
27
- after do
28
- Sidekiq.logger = @old_logger
29
- end
30
-
31
- it "logs the exception to Sidekiq.logger" do
32
- Component.new.invoke_exception(:a => 1)
33
- @str_logger.rewind
34
- log = @str_logger.readlines
35
- assert_match(/a=>1/, log[0], "didn't include the context")
36
- assert_match(/Something didn't work!/, log[1], "didn't include the exception message")
37
- assert_match(/test\/test_exception_handler.rb/, log[2], "didn't include the backtrace")
38
- end
39
-
40
- describe "when the exception does not have a backtrace" do
41
- it "does not fail" do
42
- exception = ExceptionHandlerTestException.new
43
- assert_nil exception.backtrace
44
-
45
- begin
46
- Component.new.handle_exception exception
47
- pass
48
- rescue StandardError
49
- flunk "failed handling a nil backtrace"
50
- end
51
- end
52
- end
53
- end
54
-
55
- end
@@ -1,126 +0,0 @@
1
- require_relative 'helper'
2
- require 'sidekiq'
3
- require 'active_record'
4
- require 'action_mailer'
5
- require 'sidekiq/extensions/action_mailer'
6
- require 'sidekiq/extensions/active_record'
7
- require 'sidekiq/rails'
8
-
9
- Sidekiq.hook_rails!
10
-
11
- class TestExtensions < Sidekiq::Test
12
- describe 'sidekiq extensions' do
13
- before do
14
- Sidekiq.redis = REDIS
15
- Sidekiq.redis {|c| c.flushdb }
16
- end
17
-
18
- class MyModel < ActiveRecord::Base
19
- def self.long_class_method
20
- raise "Should not be called!"
21
- end
22
- end
23
-
24
- it 'allows delayed execution of ActiveRecord class methods' do
25
- assert_equal [], Sidekiq::Queue.all.map(&:name)
26
- q = Sidekiq::Queue.new
27
- assert_equal 0, q.size
28
- MyModel.delay.long_class_method
29
- assert_equal ['default'], Sidekiq::Queue.all.map(&:name)
30
- assert_equal 1, q.size
31
- end
32
-
33
- it 'uses and stringifies specified options' do
34
- assert_equal [], Sidekiq::Queue.all.map(&:name)
35
- q = Sidekiq::Queue.new('notdefault')
36
- assert_equal 0, q.size
37
- MyModel.delay(queue: :notdefault).long_class_method
38
- assert_equal ['notdefault'], Sidekiq::Queue.all.map(&:name)
39
- assert_equal 1, q.size
40
- end
41
-
42
- it 'allows delayed scheduling of AR class methods' do
43
- ss = Sidekiq::ScheduledSet.new
44
- assert_equal 0, ss.size
45
- MyModel.delay_for(5.days).long_class_method
46
- assert_equal 1, ss.size
47
- end
48
-
49
- it 'allows until delayed scheduling of AR class methods' do
50
- ss = Sidekiq::ScheduledSet.new
51
- assert_equal 0, ss.size
52
- MyModel.delay_until(1.day.from_now).long_class_method
53
- assert_equal 1, ss.size
54
- end
55
-
56
- class UserMailer < ActionMailer::Base
57
- def greetings(a, b)
58
- raise "Should not be called!"
59
- end
60
- end
61
-
62
- it 'allows delayed delivery of ActionMailer mails' do
63
- assert_equal [], Sidekiq::Queue.all.map(&:name)
64
- q = Sidekiq::Queue.new
65
- assert_equal 0, q.size
66
- UserMailer.delay.greetings(1, 2)
67
- assert_equal ['default'], Sidekiq::Queue.all.map(&:name)
68
- assert_equal 1, q.size
69
- end
70
-
71
- it 'allows delayed scheduling of AM mails' do
72
- ss = Sidekiq::ScheduledSet.new
73
- assert_equal 0, ss.size
74
- UserMailer.delay_for(5.days).greetings(1, 2)
75
- assert_equal 1, ss.size
76
- end
77
-
78
- it 'allows until delay scheduling of AM mails' do
79
- ss = Sidekiq::ScheduledSet.new
80
- assert_equal 0, ss.size
81
- UserMailer.delay_until(5.days.from_now).greetings(1, 2)
82
- assert_equal 1, ss.size
83
- end
84
-
85
- class SomeClass
86
- def self.doit(arg)
87
- end
88
- end
89
-
90
- it 'allows delay of any ole class method' do
91
- q = Sidekiq::Queue.new
92
- assert_equal 0, q.size
93
- SomeClass.delay.doit(Date.today)
94
- assert_equal 1, q.size
95
- end
96
-
97
- module SomeModule
98
- def self.doit(arg)
99
- end
100
- end
101
-
102
- it 'allows delay of any module class method' do
103
- q = Sidekiq::Queue.new
104
- assert_equal 0, q.size
105
- SomeModule.delay.doit(Date.today)
106
- assert_equal 1, q.size
107
- end
108
-
109
- it 'allows removing of the #delay methods' do
110
- q = Sidekiq::Queue.new
111
- Sidekiq.remove_delay!
112
- assert_equal 0, q.size
113
- assert_raises NoMethodError do
114
- SomeModule.delay.doit(Date.today)
115
- end
116
-
117
- Sidekiq.instance_eval { remove_instance_variable :@delay_removed }
118
- # Reload modified modules
119
- load 'sidekiq/extensions/action_mailer.rb'
120
- load 'sidekiq/extensions/active_record.rb'
121
- load 'sidekiq/extensions/generic_proxy.rb'
122
- load 'sidekiq/extensions/class_methods.rb'
123
- end
124
- end
125
-
126
- end
@@ -1,104 +0,0 @@
1
- require_relative 'helper'
2
- require 'sidekiq/fetch'
3
-
4
- class TestFetcher < Sidekiq::Test
5
- describe 'fetcher' do
6
- before do
7
- Sidekiq.redis = { :url => REDIS_URL, :namespace => 'fuzzy' }
8
- Sidekiq.redis do |conn|
9
- conn.flushdb
10
- conn.rpush('queue:basic', 'msg')
11
- end
12
- end
13
-
14
- after do
15
- Sidekiq.redis = REDIS
16
- end
17
-
18
- it 'retrieves' do
19
- fetch = Sidekiq::BasicFetch.new(:queues => ['basic', 'bar'])
20
- uow = fetch.retrieve_work
21
- refute_nil uow
22
- assert_equal 'basic', uow.queue_name
23
- assert_equal 'msg', uow.message
24
- q = Sidekiq::Queue.new('basic')
25
- assert_equal 0, q.size
26
- uow.requeue
27
- assert_equal 1, q.size
28
- assert_nil uow.acknowledge
29
- end
30
-
31
- it 'retrieves with strict setting' do
32
- fetch = Sidekiq::BasicFetch.new(:queues => ['basic', 'bar', 'bar'], :strict => true)
33
- cmd = fetch.queues_cmd
34
- assert_equal cmd, ['queue:basic', 'queue:bar', 1]
35
- end
36
-
37
- it 'bulk requeues' do
38
- q1 = Sidekiq::Queue.new('foo')
39
- q2 = Sidekiq::Queue.new('bar')
40
- assert_equal 0, q1.size
41
- assert_equal 0, q2.size
42
- uow = Sidekiq::BasicFetch::UnitOfWork
43
- Sidekiq::BasicFetch.bulk_requeue([uow.new('fuzzy:queue:foo', 'bob'), uow.new('fuzzy:queue:foo', 'bar'), uow.new('fuzzy:queue:bar', 'widget')], {:queues => []})
44
- assert_equal 2, q1.size
45
- assert_equal 1, q2.size
46
- end
47
-
48
- describe 'fetching' do
49
- before do
50
- Sidekiq::Fetcher.reset
51
- end
52
-
53
- it 'instantiates' do
54
- begin
55
- Sidekiq.options[:fetch] = NullFetch
56
- mgr = Minitest::Mock.new
57
- fetch = Sidekiq::Fetcher.new(mgr, {})
58
- fetch.fetch
59
- Sidekiq::Fetcher.done!
60
- ensure
61
- Sidekiq.options[:fetch] = Sidekiq::BasicFetch
62
- end
63
- end
64
-
65
- class NullFetch
66
- def initialize(opts)
67
- end
68
- def retrieve_work
69
- end
70
- def self.bulk_requeue(*args)
71
- end
72
- end
73
-
74
- it 'handles redis network errors' do
75
- begin
76
- Sidekiq.logger.level = Logger::FATAL
77
- Sidekiq.options[:fetch] = ErrorFetch
78
- mgr = Minitest::Mock.new
79
- fetch = Sidekiq::Fetcher.new(mgr, {})
80
- def fetch.pause
81
- end
82
- refute fetch.down
83
- fetch.fetch
84
- Sidekiq::Fetcher.done!
85
- assert fetch.down
86
- ensure
87
- Sidekiq.options[:fetch] = Sidekiq::BasicFetch
88
- Sidekiq.logger.level = Logger::ERROR
89
- end
90
- end
91
-
92
- class ErrorFetch
93
- def initialize(opts)
94
- end
95
- def retrieve_work
96
- raise IOError, "ker-BOOM"
97
- end
98
- def self.bulk_requeue(*args)
99
- end
100
- end
101
- end
102
-
103
- end
104
- end
@@ -1,34 +0,0 @@
1
- require_relative 'helper'
2
- require 'sidekiq/logging'
3
-
4
- class TestLogging < Sidekiq::Test
5
- describe Sidekiq::Logging do
6
- describe "#with_context" do
7
- def context
8
- Sidekiq::Logging.logger.formatter.context
9
- end
10
-
11
- it "has no context by default" do
12
- context.must_equal nil
13
- end
14
-
15
- it "can add a context" do
16
- Sidekiq::Logging.with_context "xx" do
17
- context.must_equal " xx"
18
- end
19
- context.must_equal nil
20
- end
21
-
22
- it "can use multiple contexts" do
23
- Sidekiq::Logging.with_context "xx" do
24
- context.must_equal " xx"
25
- Sidekiq::Logging.with_context "yy" do
26
- context.must_equal " xx yy"
27
- end
28
- context.must_equal " xx"
29
- end
30
- context.must_equal nil
31
- end
32
- end
33
- end
34
- end
@@ -1,168 +0,0 @@
1
- require_relative 'helper'
2
- require 'sidekiq/manager'
3
-
4
- class TestManager < Sidekiq::Test
5
-
6
- describe 'manager' do
7
- before do
8
- Sidekiq.redis {|c| c.flushdb }
9
- end
10
-
11
- def new_manager(opts)
12
- condvar = Minitest::Mock.new
13
- condvar.expect(:signal, nil, [])
14
- Sidekiq::Manager.new(condvar, opts)
15
- end
16
-
17
- it 'creates N processor instances' do
18
- mgr = new_manager(options)
19
- assert_equal options[:concurrency], mgr.ready.size
20
- assert_equal [], mgr.busy
21
- end
22
-
23
- it 'assigns work to a processor' do
24
- uow = Object.new
25
- processor = Minitest::Mock.new
26
- processor.expect(:async, processor, [])
27
- processor.expect(:process, nil, [uow])
28
-
29
- mgr = new_manager(options)
30
- mgr.ready << processor
31
- mgr.assign(uow)
32
- assert_equal 1, mgr.busy.size
33
-
34
- processor.verify
35
- end
36
-
37
- it 'requeues work if stopping' do
38
- uow = Minitest::Mock.new
39
- uow.expect(:requeue, nil, [])
40
-
41
- mgr = new_manager(options)
42
- mgr.fetcher = Sidekiq::BasicFetch.new({:queues => []})
43
- mgr.stop
44
- mgr.assign(uow)
45
- uow.verify
46
- end
47
-
48
- it 'shuts down the system' do
49
- mgr = new_manager(options)
50
- mgr.fetcher = Sidekiq::BasicFetch.new({:queues => []})
51
- mgr.stop
52
-
53
- assert mgr.busy.empty?
54
- assert mgr.ready.empty?
55
- end
56
-
57
- it 'returns finished processors to the ready pool' do
58
- fetcher = MiniTest::Mock.new
59
- fetcher.expect :async, fetcher, []
60
- fetcher.expect :fetch, nil, []
61
- mgr = new_manager(options)
62
- mgr.fetcher = fetcher
63
- init_size = mgr.ready.size
64
- processor = mgr.ready.pop
65
- mgr.busy << processor
66
- mgr.processor_done(processor)
67
-
68
- assert_equal 0, mgr.busy.size
69
- assert_equal init_size, mgr.ready.size
70
- fetcher.verify
71
- end
72
-
73
- it 'throws away dead processors' do
74
- fetcher = MiniTest::Mock.new
75
- fetcher.expect :async, fetcher, []
76
- fetcher.expect :fetch, nil, []
77
- mgr = new_manager(options)
78
- mgr.fetcher = fetcher
79
- init_size = mgr.ready.size
80
- processor = mgr.ready.pop
81
- mgr.busy << processor
82
- mgr.processor_died(processor, 'ignored')
83
-
84
- assert_equal 0, mgr.busy.size
85
- assert_equal init_size, mgr.ready.size
86
- refute mgr.ready.include?(processor)
87
- fetcher.verify
88
- end
89
-
90
- it 'does not support invalid concurrency' do
91
- assert_raises(ArgumentError) { new_manager(concurrency: 0) }
92
- assert_raises(ArgumentError) { new_manager(concurrency: -1) }
93
- end
94
-
95
- describe 'heartbeat' do
96
- before do
97
- uow = Object.new
98
-
99
- @processor = Minitest::Mock.new
100
- @processor.expect(:async, @processor, [])
101
- @processor.expect(:process, nil, [uow])
102
-
103
- @mgr = new_manager(options)
104
- @mgr.ready << @processor
105
- @mgr.assign(uow)
106
-
107
- @processor.verify
108
- @proctitle = $0
109
- end
110
-
111
- after do
112
- $0 = @proctitle
113
- end
114
-
115
- describe 'when manager is active' do
116
- before do
117
- Sidekiq::Manager::PROCTITLES << proc { "xyz" }
118
- @mgr.heartbeat('identity', heartbeat_data, Sidekiq.dump_json(heartbeat_data))
119
- Sidekiq::Manager::PROCTITLES.pop
120
- end
121
-
122
- it 'sets useful info to proctitle' do
123
- assert_equal "sidekiq #{Sidekiq::VERSION} myapp [1 of 3 busy] xyz", $0
124
- end
125
-
126
- it 'stores process info in redis' do
127
- info = Sidekiq.redis { |c| c.hmget('identity', 'busy') }
128
- assert_equal ["1"], info
129
- expires = Sidekiq.redis { |c| c.pttl('identity') }
130
- assert_in_delta 60000, expires, 500
131
- end
132
- end
133
-
134
- describe 'when manager is stopped' do
135
- before do
136
- @processor.expect(:alive?, [])
137
- @processor.expect(:terminate, [])
138
-
139
- @mgr.stop
140
- @mgr.processor_done(@processor)
141
- @mgr.heartbeat('identity', heartbeat_data, Sidekiq.dump_json(heartbeat_data))
142
-
143
- @processor.verify
144
- end
145
-
146
- it 'indicates stopping status in proctitle' do
147
- assert_equal "sidekiq #{Sidekiq::VERSION} myapp [0 of 3 busy] stopping", $0
148
- end
149
-
150
- it 'stores process info in redis' do
151
- info = Sidekiq.redis { |c| c.hmget('identity', 'busy') }
152
- assert_equal ["0"], info
153
- expires = Sidekiq.redis { |c| c.pttl('identity') }
154
- assert_in_delta 60000, expires, 50
155
- end
156
- end
157
- end
158
-
159
- def options
160
- { :concurrency => 3, :queues => ['default'] }
161
- end
162
-
163
- def heartbeat_data
164
- { 'concurrency' => 3, 'tag' => 'myapp' }
165
- end
166
- end
167
-
168
- end