sidekiq 3.5.4 → 7.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. checksums.yaml +5 -5
  2. data/Changes.md +992 -6
  3. data/LICENSE.txt +9 -0
  4. data/README.md +52 -43
  5. data/bin/sidekiq +22 -4
  6. data/bin/sidekiqload +209 -115
  7. data/bin/sidekiqmon +11 -0
  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/job_spec.rb.erb +6 -0
  11. data/lib/generators/sidekiq/templates/job_test.rb.erb +8 -0
  12. data/lib/sidekiq/api.rb +633 -295
  13. data/lib/sidekiq/capsule.rb +127 -0
  14. data/lib/sidekiq/cli.rb +270 -248
  15. data/lib/sidekiq/client.rb +139 -108
  16. data/lib/sidekiq/component.rb +68 -0
  17. data/lib/sidekiq/config.rb +287 -0
  18. data/lib/sidekiq/deploy.rb +62 -0
  19. data/lib/sidekiq/embedded.rb +61 -0
  20. data/lib/sidekiq/fetch.rb +53 -121
  21. data/lib/sidekiq/job.rb +374 -0
  22. data/lib/sidekiq/job_logger.rb +51 -0
  23. data/lib/sidekiq/job_retry.rb +301 -0
  24. data/lib/sidekiq/job_util.rb +107 -0
  25. data/lib/sidekiq/launcher.rb +241 -69
  26. data/lib/sidekiq/logger.rb +131 -0
  27. data/lib/sidekiq/manager.rb +88 -190
  28. data/lib/sidekiq/metrics/query.rb +155 -0
  29. data/lib/sidekiq/metrics/shared.rb +95 -0
  30. data/lib/sidekiq/metrics/tracking.rb +136 -0
  31. data/lib/sidekiq/middleware/chain.rb +114 -56
  32. data/lib/sidekiq/middleware/current_attributes.rb +95 -0
  33. data/lib/sidekiq/middleware/i18n.rb +8 -7
  34. data/lib/sidekiq/middleware/modules.rb +21 -0
  35. data/lib/sidekiq/monitor.rb +146 -0
  36. data/lib/sidekiq/paginator.rb +29 -16
  37. data/lib/sidekiq/processor.rb +238 -118
  38. data/lib/sidekiq/rails.rb +57 -27
  39. data/lib/sidekiq/redis_client_adapter.rb +111 -0
  40. data/lib/sidekiq/redis_connection.rb +49 -50
  41. data/lib/sidekiq/ring_buffer.rb +29 -0
  42. data/lib/sidekiq/scheduled.rb +173 -52
  43. data/lib/sidekiq/sd_notify.rb +149 -0
  44. data/lib/sidekiq/systemd.rb +24 -0
  45. data/lib/sidekiq/testing/inline.rb +7 -5
  46. data/lib/sidekiq/testing.rb +197 -65
  47. data/lib/sidekiq/transaction_aware_client.rb +44 -0
  48. data/lib/sidekiq/version.rb +4 -1
  49. data/lib/sidekiq/web/action.rb +93 -0
  50. data/lib/sidekiq/web/application.rb +463 -0
  51. data/lib/sidekiq/web/csrf_protection.rb +180 -0
  52. data/lib/sidekiq/web/helpers.rb +364 -0
  53. data/lib/sidekiq/web/router.rb +104 -0
  54. data/lib/sidekiq/web.rb +113 -216
  55. data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
  56. data/lib/sidekiq.rb +99 -142
  57. data/sidekiq.gemspec +26 -23
  58. data/web/assets/images/apple-touch-icon.png +0 -0
  59. data/web/assets/javascripts/application.js +163 -74
  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 +182 -0
  64. data/web/assets/javascripts/dashboard.js +37 -280
  65. data/web/assets/javascripts/metrics.js +298 -0
  66. data/web/assets/stylesheets/application-dark.css +147 -0
  67. data/web/assets/stylesheets/application-rtl.css +153 -0
  68. data/web/assets/stylesheets/application.css +181 -198
  69. data/web/assets/stylesheets/bootstrap-rtl.min.css +9 -0
  70. data/web/assets/stylesheets/bootstrap.css +4 -8
  71. data/web/locales/ar.yml +87 -0
  72. data/web/locales/cs.yml +62 -52
  73. data/web/locales/da.yml +60 -53
  74. data/web/locales/de.yml +65 -53
  75. data/web/locales/el.yml +43 -24
  76. data/web/locales/en.yml +86 -62
  77. data/web/locales/es.yml +70 -53
  78. data/web/locales/fa.yml +80 -0
  79. data/web/locales/fr.yml +86 -56
  80. data/web/locales/gd.yml +99 -0
  81. data/web/locales/he.yml +80 -0
  82. data/web/locales/hi.yml +59 -59
  83. data/web/locales/it.yml +53 -53
  84. data/web/locales/ja.yml +78 -56
  85. data/web/locales/ko.yml +52 -52
  86. data/web/locales/lt.yml +83 -0
  87. data/web/locales/nb.yml +61 -61
  88. data/web/locales/nl.yml +52 -52
  89. data/web/locales/pl.yml +45 -45
  90. data/web/locales/pt-br.yml +83 -55
  91. data/web/locales/pt.yml +51 -51
  92. data/web/locales/ru.yml +68 -60
  93. data/web/locales/sv.yml +53 -53
  94. data/web/locales/ta.yml +60 -60
  95. data/web/locales/uk.yml +62 -61
  96. data/web/locales/ur.yml +80 -0
  97. data/web/locales/vi.yml +83 -0
  98. data/web/locales/zh-cn.yml +43 -16
  99. data/web/locales/zh-tw.yml +42 -8
  100. data/web/views/_footer.erb +10 -9
  101. data/web/views/_job_info.erb +26 -5
  102. data/web/views/_metrics_period_select.erb +12 -0
  103. data/web/views/_nav.erb +6 -20
  104. data/web/views/_paging.erb +3 -1
  105. data/web/views/_poll_link.erb +3 -6
  106. data/web/views/_summary.erb +7 -7
  107. data/web/views/busy.erb +87 -28
  108. data/web/views/dashboard.erb +51 -21
  109. data/web/views/dead.erb +4 -4
  110. data/web/views/filtering.erb +7 -0
  111. data/web/views/layout.erb +15 -5
  112. data/web/views/metrics.erb +91 -0
  113. data/web/views/metrics_for_job.erb +59 -0
  114. data/web/views/morgue.erb +25 -22
  115. data/web/views/queue.erb +35 -25
  116. data/web/views/queues.erb +23 -7
  117. data/web/views/retries.erb +28 -23
  118. data/web/views/retry.erb +5 -5
  119. data/web/views/scheduled.erb +19 -17
  120. data/web/views/scheduled_job_info.erb +1 -1
  121. metadata +86 -268
  122. data/.gitignore +0 -12
  123. data/.travis.yml +0 -16
  124. data/3.0-Upgrade.md +0 -70
  125. data/COMM-LICENSE +0 -95
  126. data/Contributing.md +0 -32
  127. data/Ent-Changes.md +0 -39
  128. data/Gemfile +0 -27
  129. data/LICENSE +0 -9
  130. data/Pro-2.0-Upgrade.md +0 -138
  131. data/Pro-Changes.md +0 -454
  132. data/Rakefile +0 -9
  133. data/bin/sidekiqctl +0 -93
  134. data/lib/generators/sidekiq/templates/worker_spec.rb.erb +0 -6
  135. data/lib/generators/sidekiq/templates/worker_test.rb.erb +0 -8
  136. data/lib/generators/sidekiq/worker_generator.rb +0 -49
  137. data/lib/sidekiq/actor.rb +0 -39
  138. data/lib/sidekiq/core_ext.rb +0 -105
  139. data/lib/sidekiq/exception_handler.rb +0 -30
  140. data/lib/sidekiq/extensions/action_mailer.rb +0 -56
  141. data/lib/sidekiq/extensions/active_record.rb +0 -39
  142. data/lib/sidekiq/extensions/class_methods.rb +0 -39
  143. data/lib/sidekiq/extensions/generic_proxy.rb +0 -24
  144. data/lib/sidekiq/logging.rb +0 -104
  145. data/lib/sidekiq/middleware/server/active_record.rb +0 -13
  146. data/lib/sidekiq/middleware/server/logging.rb +0 -40
  147. data/lib/sidekiq/middleware/server/retry_jobs.rb +0 -206
  148. data/lib/sidekiq/util.rb +0 -68
  149. data/lib/sidekiq/web_helpers.rb +0 -249
  150. data/lib/sidekiq/worker.rb +0 -103
  151. data/test/config.yml +0 -9
  152. data/test/env_based_config.yml +0 -11
  153. data/test/fake_env.rb +0 -0
  154. data/test/fixtures/en.yml +0 -2
  155. data/test/helper.rb +0 -49
  156. data/test/test_api.rb +0 -493
  157. data/test/test_cli.rb +0 -335
  158. data/test/test_client.rb +0 -194
  159. data/test/test_exception_handler.rb +0 -55
  160. data/test/test_extensions.rb +0 -126
  161. data/test/test_fetch.rb +0 -104
  162. data/test/test_logging.rb +0 -34
  163. data/test/test_manager.rb +0 -168
  164. data/test/test_middleware.rb +0 -159
  165. data/test/test_processor.rb +0 -237
  166. data/test/test_rails.rb +0 -21
  167. data/test/test_redis_connection.rb +0 -126
  168. data/test/test_retry.rb +0 -325
  169. data/test/test_scheduled.rb +0 -114
  170. data/test/test_scheduling.rb +0 -49
  171. data/test/test_sidekiq.rb +0 -99
  172. data/test/test_testing.rb +0 -142
  173. data/test/test_testing_fake.rb +0 -268
  174. data/test/test_testing_inline.rb +0 -93
  175. data/test/test_util.rb +0 -16
  176. data/test/test_web.rb +0 -608
  177. data/test/test_web_helpers.rb +0 -53
  178. data/web/assets/images/bootstrap/glyphicons-halflings-white.png +0 -0
  179. data/web/assets/images/bootstrap/glyphicons-halflings.png +0 -0
  180. data/web/assets/images/status/active.png +0 -0
  181. data/web/assets/images/status/idle.png +0 -0
  182. data/web/assets/javascripts/locales/README.md +0 -27
  183. data/web/assets/javascripts/locales/jquery.timeago.ar.js +0 -96
  184. data/web/assets/javascripts/locales/jquery.timeago.bg.js +0 -18
  185. data/web/assets/javascripts/locales/jquery.timeago.bs.js +0 -49
  186. data/web/assets/javascripts/locales/jquery.timeago.ca.js +0 -18
  187. data/web/assets/javascripts/locales/jquery.timeago.cs.js +0 -18
  188. data/web/assets/javascripts/locales/jquery.timeago.cy.js +0 -20
  189. data/web/assets/javascripts/locales/jquery.timeago.da.js +0 -18
  190. data/web/assets/javascripts/locales/jquery.timeago.de.js +0 -18
  191. data/web/assets/javascripts/locales/jquery.timeago.el.js +0 -18
  192. data/web/assets/javascripts/locales/jquery.timeago.en-short.js +0 -20
  193. data/web/assets/javascripts/locales/jquery.timeago.en.js +0 -20
  194. data/web/assets/javascripts/locales/jquery.timeago.es.js +0 -18
  195. data/web/assets/javascripts/locales/jquery.timeago.et.js +0 -18
  196. data/web/assets/javascripts/locales/jquery.timeago.fa.js +0 -22
  197. data/web/assets/javascripts/locales/jquery.timeago.fi.js +0 -28
  198. data/web/assets/javascripts/locales/jquery.timeago.fr-short.js +0 -16
  199. data/web/assets/javascripts/locales/jquery.timeago.fr.js +0 -17
  200. data/web/assets/javascripts/locales/jquery.timeago.he.js +0 -18
  201. data/web/assets/javascripts/locales/jquery.timeago.hr.js +0 -49
  202. data/web/assets/javascripts/locales/jquery.timeago.hu.js +0 -18
  203. data/web/assets/javascripts/locales/jquery.timeago.hy.js +0 -18
  204. data/web/assets/javascripts/locales/jquery.timeago.id.js +0 -18
  205. data/web/assets/javascripts/locales/jquery.timeago.it.js +0 -16
  206. data/web/assets/javascripts/locales/jquery.timeago.ja.js +0 -19
  207. data/web/assets/javascripts/locales/jquery.timeago.ko.js +0 -17
  208. data/web/assets/javascripts/locales/jquery.timeago.lt.js +0 -20
  209. data/web/assets/javascripts/locales/jquery.timeago.mk.js +0 -20
  210. data/web/assets/javascripts/locales/jquery.timeago.nl.js +0 -20
  211. data/web/assets/javascripts/locales/jquery.timeago.no.js +0 -18
  212. data/web/assets/javascripts/locales/jquery.timeago.pl.js +0 -31
  213. data/web/assets/javascripts/locales/jquery.timeago.pt-br.js +0 -16
  214. data/web/assets/javascripts/locales/jquery.timeago.pt.js +0 -16
  215. data/web/assets/javascripts/locales/jquery.timeago.ro.js +0 -18
  216. data/web/assets/javascripts/locales/jquery.timeago.rs.js +0 -49
  217. data/web/assets/javascripts/locales/jquery.timeago.ru.js +0 -34
  218. data/web/assets/javascripts/locales/jquery.timeago.sk.js +0 -18
  219. data/web/assets/javascripts/locales/jquery.timeago.sl.js +0 -44
  220. data/web/assets/javascripts/locales/jquery.timeago.sv.js +0 -18
  221. data/web/assets/javascripts/locales/jquery.timeago.th.js +0 -20
  222. data/web/assets/javascripts/locales/jquery.timeago.tr.js +0 -16
  223. data/web/assets/javascripts/locales/jquery.timeago.uk.js +0 -34
  224. data/web/assets/javascripts/locales/jquery.timeago.uz.js +0 -19
  225. data/web/assets/javascripts/locales/jquery.timeago.zh-cn.js +0 -20
  226. data/web/assets/javascripts/locales/jquery.timeago.zh-tw.js +0 -20
  227. data/web/views/_poll_js.erb +0 -5
  228. /data/web/assets/images/{status-sd8051fd480.png → status.png} +0 -0
@@ -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
data/test/test_fetch.rb DELETED
@@ -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
data/test/test_logging.rb DELETED
@@ -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
data/test/test_manager.rb DELETED
@@ -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
@@ -1,159 +0,0 @@
1
- require_relative 'helper'
2
- require 'sidekiq/middleware/chain'
3
- require 'sidekiq/processor'
4
-
5
- class TestMiddleware < Sidekiq::Test
6
- describe 'middleware chain' do
7
- before do
8
- $errors = []
9
- Sidekiq.redis = REDIS
10
- end
11
-
12
- class CustomMiddleware
13
- def initialize(name, recorder)
14
- @name = name
15
- @recorder = recorder
16
- end
17
-
18
- def call(*args)
19
- @recorder << [@name, 'before']
20
- yield
21
- @recorder << [@name, 'after']
22
- end
23
- end
24
-
25
- it 'supports custom middleware' do
26
- chain = Sidekiq::Middleware::Chain.new
27
- chain.add CustomMiddleware, 1, []
28
-
29
- assert_equal CustomMiddleware, chain.entries.last.klass
30
- end
31
-
32
- class CustomWorker
33
- $recorder = []
34
- include Sidekiq::Worker
35
- def perform(recorder)
36
- $recorder << ['work_performed']
37
- end
38
- end
39
-
40
- class NonYieldingMiddleware
41
- def call(*args)
42
- end
43
- end
44
-
45
- class AnotherCustomMiddleware
46
- def initialize(name, recorder)
47
- @name = name
48
- @recorder = recorder
49
- end
50
-
51
- def call(*args)
52
- @recorder << [@name, 'before']
53
- yield
54
- @recorder << [@name, 'after']
55
- end
56
- end
57
-
58
- class YetAnotherCustomMiddleware
59
- def initialize(name, recorder)
60
- @name = name
61
- @recorder = recorder
62
- end
63
-
64
- def call(*args)
65
- @recorder << [@name, 'before']
66
- yield
67
- @recorder << [@name, 'after']
68
- end
69
- end
70
-
71
- it 'executes middleware in the proper order' do
72
- msg = Sidekiq.dump_json({ 'class' => CustomWorker.to_s, 'args' => [$recorder] })
73
-
74
- Sidekiq.server_middleware do |chain|
75
- # should only add once, second should replace the first
76
- 2.times { |i| chain.add CustomMiddleware, i.to_s, $recorder }
77
- chain.insert_before CustomMiddleware, AnotherCustomMiddleware, '2', $recorder
78
- chain.insert_after AnotherCustomMiddleware, YetAnotherCustomMiddleware, '3', $recorder
79
- end
80
-
81
- boss = Minitest::Mock.new
82
- processor = Sidekiq::Processor.new(boss)
83
- actor = Minitest::Mock.new
84
- actor.expect(:processor_done, nil, [processor])
85
- actor.expect(:real_thread, nil, [nil, Thread])
86
- boss.expect(:async, actor, [])
87
- boss.expect(:async, actor, [])
88
- processor.process(Sidekiq::BasicFetch::UnitOfWork.new('queue:default', msg))
89
- assert_equal %w(2 before 3 before 1 before work_performed 1 after 3 after 2 after), $recorder.flatten
90
- end
91
-
92
- it 'correctly replaces middleware when using middleware with options in the initializer' do
93
- chain = Sidekiq::Middleware::Chain.new
94
- chain.add Sidekiq::Middleware::Server::RetryJobs
95
- chain.add Sidekiq::Middleware::Server::RetryJobs, {:max_retries => 5}
96
- assert_equal 1, chain.count
97
- end
98
-
99
- it 'correctly prepends middleware' do
100
- chain = Sidekiq::Middleware::Chain.new
101
- chain_entries = chain.entries
102
- chain.add CustomMiddleware
103
- chain.prepend YetAnotherCustomMiddleware
104
- assert_equal YetAnotherCustomMiddleware, chain_entries.first.klass
105
- assert_equal CustomMiddleware, chain_entries.last.klass
106
- end
107
-
108
- it 'allows middleware to abruptly stop processing rest of chain' do
109
- recorder = []
110
- chain = Sidekiq::Middleware::Chain.new
111
- chain.add NonYieldingMiddleware
112
- chain.add CustomMiddleware, 1, recorder
113
-
114
- final_action = nil
115
- chain.invoke { final_action = true }
116
- assert_equal nil, final_action
117
- assert_equal [], recorder
118
- end
119
- end
120
-
121
- describe 'i18n' do
122
- before do
123
- require 'i18n'
124
- I18n.enforce_available_locales = false
125
- require 'sidekiq/middleware/i18n'
126
- end
127
-
128
- it 'saves and restores locale' do
129
- I18n.locale = 'fr'
130
- msg = {}
131
- mw = Sidekiq::Middleware::I18n::Client.new
132
- mw.call(nil, msg, nil, nil) { }
133
- assert_equal :fr, msg['locale']
134
-
135
- msg['locale'] = 'jp'
136
- I18n.locale = I18n.default_locale
137
- assert_equal :en, I18n.locale
138
- mw = Sidekiq::Middleware::I18n::Server.new
139
- mw.call(nil, msg, nil) do
140
- assert_equal :jp, I18n.locale
141
- end
142
- assert_equal :en, I18n.locale
143
- end
144
-
145
- it 'supports I18n.enforce_available_locales = true' do
146
- I18n.enforce_available_locales = true
147
- I18n.available_locales = [:en, :jp]
148
-
149
- msg = { 'locale' => 'jp' }
150
- mw = Sidekiq::Middleware::I18n::Server.new
151
- mw.call(nil, msg, nil) do
152
- assert_equal :jp, I18n.locale
153
- end
154
-
155
- I18n.enforce_available_locales = false
156
- I18n.available_locales = nil
157
- end
158
- end
159
- end