sidekiq 3.5.4 → 7.2.0

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 (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,237 +0,0 @@
1
- require_relative 'helper'
2
- require 'sidekiq/processor'
3
-
4
- class TestProcessor < Sidekiq::Test
5
- TestException = Class.new(StandardError)
6
- TEST_EXCEPTION = TestException.new("kerboom!")
7
-
8
- describe 'with mock setup' do
9
- before do
10
- $invokes = 0
11
- @boss = Minitest::Mock.new
12
- @processor = ::Sidekiq::Processor.new(@boss)
13
- end
14
-
15
- class MockWorker
16
- include Sidekiq::Worker
17
- def perform(args)
18
- raise TEST_EXCEPTION if args == 'boom'
19
- args.pop if args.is_a? Array
20
- $invokes += 1
21
- end
22
- end
23
-
24
- def work(msg, queue='queue:default')
25
- Sidekiq::BasicFetch::UnitOfWork.new(queue, msg)
26
- end
27
-
28
- it 'processes as expected' do
29
- msg = Sidekiq.dump_json({ 'class' => MockWorker.to_s, 'args' => ['myarg'] })
30
- actor = Minitest::Mock.new
31
- actor.expect(:processor_done, nil, [@processor])
32
- actor.expect(:real_thread, nil, [nil, Thread])
33
- @boss.expect(:async, actor, [])
34
- @boss.expect(:async, actor, [])
35
- @processor.process(work(msg))
36
- @boss.verify
37
- assert_equal 1, $invokes
38
- end
39
-
40
- it 'executes a worker as expected' do
41
- worker = Minitest::Mock.new
42
- worker.expect(:perform, nil, [1, 2, 3])
43
- @processor.execute_job(worker, [1, 2, 3])
44
- end
45
-
46
- it 'passes exceptions to ExceptionHandler' do
47
- actor = Minitest::Mock.new
48
- actor.expect(:real_thread, nil, [nil, Thread])
49
- @boss.expect(:async, actor, [])
50
- msg = Sidekiq.dump_json({ 'class' => MockWorker.to_s, 'args' => ['boom'] })
51
- begin
52
- @processor.process(work(msg))
53
- flunk "Expected #process to raise exception"
54
- rescue TestException
55
- end
56
-
57
- assert_equal 0, $invokes
58
- end
59
-
60
- it 're-raises exceptions after handling' do
61
- msg = Sidekiq.dump_json({ 'class' => MockWorker.to_s, 'args' => ['boom'] })
62
- re_raise = false
63
- actor = Minitest::Mock.new
64
- actor.expect(:real_thread, nil, [nil, Thread])
65
- @boss.expect(:async, actor, [])
66
-
67
- begin
68
- @processor.process(work(msg))
69
- rescue TestException
70
- re_raise = true
71
- end
72
-
73
- assert re_raise, "does not re-raise exceptions after handling"
74
- end
75
-
76
- it 'does not modify original arguments' do
77
- msg = { 'class' => MockWorker.to_s, 'args' => [['myarg']] }
78
- msgstr = Sidekiq.dump_json(msg)
79
- processor = ::Sidekiq::Processor.new(@boss)
80
- actor = Minitest::Mock.new
81
- actor.expect(:processor_done, nil, [processor])
82
- actor.expect(:real_thread, nil, [nil, Thread])
83
- @boss.expect(:async, actor, [])
84
- @boss.expect(:async, actor, [])
85
- processor.process(work(msgstr))
86
- assert_equal [['myarg']], msg['args']
87
- end
88
-
89
- describe 'acknowledgement' do
90
- class ExceptionRaisingMiddleware
91
- def initialize(raise_before_yield, raise_after_yield, skip)
92
- @raise_before_yield = raise_before_yield
93
- @raise_after_yield = raise_after_yield
94
- @skip = skip
95
- end
96
-
97
- def call(worker, item, queue)
98
- raise TEST_EXCEPTION if @raise_before_yield
99
- yield unless @skip
100
- raise TEST_EXCEPTION if @raise_after_yield
101
- end
102
- end
103
-
104
- let(:raise_before_yield) { false }
105
- let(:raise_after_yield) { false }
106
- let(:skip_job) { false }
107
- let(:worker_args) { ['myarg'] }
108
- let(:work) { MiniTest::Mock.new }
109
- let(:actor) { Minitest::Mock.new }
110
-
111
- before do
112
- work.expect(:queue_name, 'queues:default')
113
- work.expect(:message, Sidekiq.dump_json({ 'class' => MockWorker.to_s, 'args' => worker_args }))
114
- Sidekiq.server_middleware do |chain|
115
- chain.prepend ExceptionRaisingMiddleware, raise_before_yield, raise_after_yield, skip_job
116
- end
117
-
118
- actor.expect(:real_thread, nil, [nil, Thread])
119
- @boss.expect(:async, actor, [])
120
- end
121
-
122
- after do
123
- Sidekiq.server_middleware do |chain|
124
- chain.remove ExceptionRaisingMiddleware
125
- end
126
- work.verify
127
- end
128
-
129
- describe 'middleware throws an exception before processing the work' do
130
- let(:raise_before_yield) { true }
131
-
132
- it 'does not ack' do
133
- begin
134
- @processor.process(work)
135
- flunk "Expected #process to raise exception"
136
- rescue TestException
137
- end
138
- end
139
- end
140
-
141
- describe 'middleware throws an exception after processing the work' do
142
- let(:raise_after_yield) { true }
143
-
144
- it 'acks the job' do
145
- work.expect(:acknowledge, nil)
146
- begin
147
- @processor.process(work)
148
- flunk "Expected #process to raise exception"
149
- rescue TestException
150
- end
151
- end
152
- end
153
-
154
- describe 'middleware decides to skip work' do
155
- let(:skip_job) { true }
156
-
157
- it 'acks the job' do
158
- work.expect(:acknowledge, nil)
159
- @boss.expect(:async, actor, [])
160
- actor.expect(:processor_done, nil, [@processor])
161
- @processor.process(work)
162
- end
163
- end
164
-
165
- describe 'worker raises an exception' do
166
- let(:worker_args) { ['boom'] }
167
-
168
- it 'acks the job' do
169
- work.expect(:acknowledge, nil)
170
- begin
171
- @processor.process(work)
172
- flunk "Expected #process to raise exception"
173
- rescue TestException
174
- end
175
- end
176
- end
177
-
178
- describe 'everything goes well' do
179
- it 'acks the job' do
180
- work.expect(:acknowledge, nil)
181
- @boss.expect(:async, actor, [])
182
- actor.expect(:processor_done, nil, [@processor])
183
- @processor.process(work)
184
- end
185
- end
186
- end
187
-
188
- describe 'stats' do
189
- before do
190
- Sidekiq.redis {|c| c.flushdb }
191
- end
192
-
193
- describe 'when successful' do
194
- let(:processed_today_key) { "stat:processed:#{Time.now.utc.strftime("%Y-%m-%d")}" }
195
-
196
- def successful_job
197
- msg = Sidekiq.dump_json({ 'class' => MockWorker.to_s, 'args' => ['myarg'] })
198
- actor = Minitest::Mock.new
199
- actor.expect(:real_thread, nil, [nil, Thread])
200
- actor.expect(:processor_done, nil, [@processor])
201
- @boss.expect(:async, actor, [])
202
- @boss.expect(:async, actor, [])
203
- @processor.process(work(msg))
204
- end
205
-
206
- it 'increments processed stat' do
207
- assert_equal 0, Sidekiq::Stats.new.processed
208
- successful_job
209
- assert_equal 1, Sidekiq::Stats.new.processed
210
- assert_equal Sidekiq::Processor::STATS_TIMEOUT, Sidekiq.redis { |conn| conn.ttl(processed_today_key) }
211
- end
212
- end
213
-
214
- describe 'when failed' do
215
- let(:failed_today_key) { "stat:failed:#{Time.now.utc.strftime("%Y-%m-%d")}" }
216
-
217
- def failed_job
218
- actor = Minitest::Mock.new
219
- actor.expect(:real_thread, nil, [nil, Thread])
220
- @boss.expect(:async, actor, [])
221
- msg = Sidekiq.dump_json({ 'class' => MockWorker.to_s, 'args' => ['boom'] })
222
- begin
223
- @processor.process(work(msg))
224
- rescue TestException
225
- end
226
- end
227
-
228
- it 'increments failed stat' do
229
- assert_equal 0, Sidekiq::Stats.new.failed
230
- failed_job
231
- assert_equal 1, Sidekiq::Stats.new.failed
232
- assert_equal Sidekiq::Processor::STATS_TIMEOUT, Sidekiq.redis { |conn| conn.ttl(failed_today_key) }
233
- end
234
- end
235
- end
236
- end
237
- end
data/test/test_rails.rb DELETED
@@ -1,21 +0,0 @@
1
- require_relative 'helper'
2
-
3
- $HAS_AJ = true
4
- begin
5
- require 'active_job'
6
- rescue LoadError
7
- $HAS_AJ = false
8
- end
9
-
10
- class TestRails < Sidekiq::Test
11
-
12
- describe 'ActiveJob' do
13
- it 'does not allow Sidekiq::Worker in AJ::Base classes' do
14
- ex = assert_raises ArgumentError do
15
- c = Class.new(ActiveJob::Base)
16
- c.send(:include, Sidekiq::Worker)
17
- end
18
- assert_includes ex.message, "cannot include"
19
- end if $HAS_AJ
20
- end
21
- end
@@ -1,126 +0,0 @@
1
- require_relative 'helper'
2
-
3
- class TestRedisConnection < Sidekiq::Test
4
-
5
- describe ".create" do
6
-
7
- it "creates a pooled redis connection" do
8
- pool = Sidekiq::RedisConnection.create
9
- assert_equal Redis, pool.checkout.class
10
- end
11
-
12
- describe "network_timeout" do
13
- it "sets a custom network_timeout if specified" do
14
- pool = Sidekiq::RedisConnection.create(:network_timeout => 8)
15
- redis = pool.checkout
16
-
17
- assert_equal 8, redis.client.timeout
18
- end
19
-
20
- it "uses the default network_timeout if none specified" do
21
- pool = Sidekiq::RedisConnection.create
22
- redis = pool.checkout
23
-
24
- assert_equal 5, redis.client.timeout
25
- end
26
- end
27
-
28
- describe "namespace" do
29
- it "uses a given :namespace" do
30
- pool = Sidekiq::RedisConnection.create(:namespace => "xxx")
31
- assert_equal "xxx", pool.checkout.namespace
32
- end
33
-
34
- it "uses given :namespace over :namespace from Sidekiq.options" do
35
- Sidekiq.options[:namespace] = "xxx"
36
- pool = Sidekiq::RedisConnection.create(:namespace => "yyy")
37
- assert_equal "yyy", pool.checkout.namespace
38
- end
39
- end
40
-
41
- describe "socket path" do
42
- it "uses a given :path" do
43
- pool = Sidekiq::RedisConnection.create(:path => "/var/run/redis.sock")
44
- assert_equal "unix", pool.checkout.client.scheme
45
- assert_equal "redis:///var/run/redis.sock/0", pool.checkout.client.id
46
- end
47
-
48
- it "uses a given :path and :db" do
49
- pool = Sidekiq::RedisConnection.create(:path => "/var/run/redis.sock", :db => 8)
50
- assert_equal "unix", pool.checkout.client.scheme
51
- assert_equal "redis:///var/run/redis.sock/8", pool.checkout.client.id
52
- end
53
- end
54
-
55
- describe "pool_timeout" do
56
- it "uses a given :timeout over the default of 1" do
57
- pool = Sidekiq::RedisConnection.create(:pool_timeout => 5)
58
-
59
- assert_equal 5, pool.instance_eval{ @timeout }
60
- end
61
-
62
- it "uses the default timeout of 1 if no override" do
63
- pool = Sidekiq::RedisConnection.create
64
-
65
- assert_equal 1, pool.instance_eval{ @timeout }
66
- end
67
- end
68
- end
69
-
70
- describe ".determine_redis_provider" do
71
-
72
- before do
73
- @old_env = ENV.to_hash
74
- end
75
-
76
- after do
77
- ENV.update(@old_env)
78
- end
79
-
80
- def with_env_var(var, uri, skip_provider=false)
81
- vars = ['REDISTOGO_URL', 'REDIS_PROVIDER', 'REDIS_URL'] - [var]
82
- vars.each do |v|
83
- next if skip_provider
84
- ENV[v] = nil
85
- end
86
- ENV[var] = uri
87
- assert_equal uri, Sidekiq::RedisConnection.__send__(:determine_redis_provider)
88
- ENV[var] = nil
89
- end
90
-
91
- describe "with REDISTOGO_URL and a parallel REDIS_PROVIDER set" do
92
- it "sets connection URI to the provider" do
93
- uri = 'redis://sidekiq-redis-provider:6379/0'
94
- provider = 'SIDEKIQ_REDIS_PROVIDER'
95
-
96
- ENV['REDIS_PROVIDER'] = provider
97
- ENV[provider] = uri
98
- ENV['REDISTOGO_URL'] = 'redis://redis-to-go:6379/0'
99
- with_env_var provider, uri, true
100
-
101
- ENV[provider] = nil
102
- end
103
- end
104
-
105
- describe "with REDIS_PROVIDER set" do
106
- it "sets connection URI to the provider" do
107
- uri = 'redis://sidekiq-redis-provider:6379/0'
108
- provider = 'SIDEKIQ_REDIS_PROVIDER'
109
-
110
- ENV['REDIS_PROVIDER'] = provider
111
- ENV[provider] = uri
112
-
113
- with_env_var provider, uri, true
114
-
115
- ENV[provider] = nil
116
- end
117
- end
118
-
119
- describe "with REDIS_URL set" do
120
- it "sets connection URI to custom uri" do
121
- with_env_var 'REDIS_URL', 'redis://redis-uri:6379/0'
122
- end
123
- end
124
-
125
- end
126
- end
data/test/test_retry.rb DELETED
@@ -1,325 +0,0 @@
1
- # encoding: utf-8
2
- require_relative 'helper'
3
- require 'sidekiq/scheduled'
4
- require 'sidekiq/middleware/server/retry_jobs'
5
-
6
- class TestRetry < Sidekiq::Test
7
- describe 'middleware' do
8
- class SomeWorker
9
- include Sidekiq::Worker
10
- end
11
-
12
- before do
13
- Sidekiq.redis {|c| c.flushdb }
14
- end
15
-
16
- def worker
17
- @worker ||= SomeWorker.new
18
- end
19
-
20
- def handler(options={})
21
- @handler ||= Sidekiq::Middleware::Server::RetryJobs.new(options)
22
- end
23
-
24
- def job(options={})
25
- @job ||= { 'class' => 'Bob', 'args' => [1,2,'foo'], 'retry' => true }.merge(options)
26
- end
27
-
28
- it 'allows disabling retry' do
29
- assert_raises RuntimeError do
30
- handler.call(worker, job('retry' => false), 'default') do
31
- raise "kerblammo!"
32
- end
33
- end
34
- assert_equal 0, Sidekiq::RetrySet.new.size
35
- end
36
-
37
- it 'allows a numeric retry' do
38
- assert_raises RuntimeError do
39
- handler.call(worker, job('retry' => 2), 'default') do
40
- raise "kerblammo!"
41
- end
42
- end
43
- assert_equal 1, Sidekiq::RetrySet.new.size
44
- assert_equal 0, Sidekiq::DeadSet.new.size
45
- end
46
-
47
- it 'allows 0 retry => no retry and dead queue' do
48
- assert_raises RuntimeError do
49
- handler.call(worker, job('retry' => 0), 'default') do
50
- raise "kerblammo!"
51
- end
52
- end
53
- assert_equal 0, Sidekiq::RetrySet.new.size
54
- assert_equal 1, Sidekiq::DeadSet.new.size
55
- end
56
-
57
- it 'handles zany characters in error message, #1705' do
58
- skip 'skipped! test requires ruby 2.1+' if RUBY_VERSION <= '2.1.0'
59
-
60
- assert_raises RuntimeError do
61
- handler.call(worker, job, 'default') do
62
- raise "kerblammo! #{195.chr}"
63
- end
64
- end
65
- assert_equal "kerblammo! �", job["error_message"]
66
- end
67
-
68
-
69
- it 'allows a max_retries option in initializer' do
70
- max_retries = 7
71
- 1.upto(max_retries + 1) do
72
- assert_raises RuntimeError do
73
- handler(:max_retries => max_retries).call(worker, job, 'default') do
74
- raise "kerblammo!"
75
- end
76
- end
77
- end
78
-
79
- assert_equal max_retries, Sidekiq::RetrySet.new.size
80
- assert_equal 1, Sidekiq::DeadSet.new.size
81
- end
82
-
83
- it 'saves backtraces' do
84
- c = nil
85
- assert_raises RuntimeError do
86
- handler.call(worker, job('backtrace' => true), 'default') do
87
- c = caller(0); raise "kerblammo!"
88
- end
89
- end
90
- assert job["error_backtrace"]
91
- assert_equal c[0], job["error_backtrace"][0]
92
- end
93
-
94
- it 'saves partial backtraces' do
95
- c = nil
96
- assert_raises RuntimeError do
97
- handler.call(worker, job('backtrace' => 3), 'default') do
98
- c = caller(0)[0...3]; raise "kerblammo!"
99
- end
100
- end
101
- assert job["error_backtrace"]
102
- assert_equal c, job["error_backtrace"]
103
- assert_equal 3, c.size
104
- end
105
-
106
- it 'handles a new failed message' do
107
- assert_raises RuntimeError do
108
- handler.call(worker, job, 'default') do
109
- raise "kerblammo!"
110
- end
111
- end
112
- assert_equal 'default', job["queue"]
113
- assert_equal 'kerblammo!', job["error_message"]
114
- assert_equal 'RuntimeError', job["error_class"]
115
- assert_equal 0, job["retry_count"]
116
- refute job["error_backtrace"]
117
- assert job["failed_at"]
118
- end
119
-
120
- it 'shuts down without retrying work-in-progress, which will resume' do
121
- rs = Sidekiq::RetrySet.new
122
- assert_equal 0, rs.size
123
- msg = { 'class' => 'Bob', 'args' => [1,2,'foo'], 'retry' => true }
124
- assert_raises Sidekiq::Shutdown do
125
- handler.call(worker, msg, 'default') do
126
- raise Sidekiq::Shutdown
127
- end
128
- end
129
- assert_equal 0, rs.size
130
- end
131
-
132
- it 'shuts down cleanly when shutdown causes exception' do
133
- skip('Not supported in Ruby < 2.1.0') if RUBY_VERSION < '2.1.0'
134
-
135
- rs = Sidekiq::RetrySet.new
136
- assert_equal 0, rs.size
137
- msg = { 'class' => 'Bob', 'args' => [1,2,'foo'], 'retry' => true }
138
- assert_raises Sidekiq::Shutdown do
139
- handler.call(worker, msg, 'default') do
140
- begin
141
- raise Sidekiq::Shutdown
142
- rescue Interrupt
143
- raise "kerblammo!"
144
- end
145
- end
146
- end
147
- assert_equal 0, rs.size
148
- end
149
-
150
- it 'shuts down cleanly when shutdown causes chained exceptions' do
151
- skip('Not supported in Ruby < 2.1.0') if RUBY_VERSION < '2.1.0'
152
-
153
- rs = Sidekiq::RetrySet.new
154
- assert_equal 0, rs.size
155
- assert_raises Sidekiq::Shutdown do
156
- handler.call(worker, job, 'default') do
157
- begin
158
- raise Sidekiq::Shutdown
159
- rescue Interrupt
160
- begin
161
- raise "kerblammo!"
162
- rescue
163
- raise "kablooie!"
164
- end
165
- end
166
- end
167
- end
168
- assert_equal 0, rs.size
169
- end
170
-
171
- it 'allows a retry queue' do
172
- assert_raises RuntimeError do
173
- handler.call(worker, job("retry_queue" => 'retryx'), 'default') do
174
- raise "kerblammo!"
175
- end
176
- end
177
- assert_equal 'retryx', job["queue"]
178
- assert_equal 'kerblammo!', job["error_message"]
179
- assert_equal 'RuntimeError', job["error_class"]
180
- assert_equal 0, job["retry_count"]
181
- refute job["error_backtrace"]
182
- assert job["failed_at"]
183
- end
184
-
185
- it 'handles a recurring failed message' do
186
- now = Time.now.to_f
187
- msg = {"queue"=>"default", "error_message"=>"kerblammo!", "error_class"=>"RuntimeError", "failed_at"=>now, "retry_count"=>10}
188
- assert_raises RuntimeError do
189
- handler.call(worker, job(msg), 'default') do
190
- raise "kerblammo!"
191
- end
192
- end
193
- assert_equal 'default', job["queue"]
194
- assert_equal 'kerblammo!', job["error_message"]
195
- assert_equal 'RuntimeError', job["error_class"]
196
- assert_equal 11, job["retry_count"]
197
- assert job["failed_at"]
198
- end
199
-
200
- it 'throws away old messages after too many retries (using the default)' do
201
- q = Sidekiq::Queue.new
202
- rs = Sidekiq::RetrySet.new
203
- ds = Sidekiq::DeadSet.new
204
- assert_equal 0, q.size
205
- assert_equal 0, rs.size
206
- assert_equal 0, ds.size
207
- now = Time.now.to_f
208
- msg = {"queue"=>"default", "error_message"=>"kerblammo!", "error_class"=>"RuntimeError", "failed_at"=>now, "retry_count"=>25}
209
- assert_raises RuntimeError do
210
- handler.call(worker, job(msg), 'default') do
211
- raise "kerblammo!"
212
- end
213
- end
214
- assert_equal 0, q.size
215
- assert_equal 0, rs.size
216
- assert_equal 1, ds.size
217
- end
218
-
219
- describe "custom retry delay" do
220
- before do
221
- @old_logger = Sidekiq.logger
222
- @tmp_log_path = '/tmp/sidekiq-retries.log'
223
- Sidekiq.logger = Logger.new(@tmp_log_path)
224
- end
225
-
226
- after do
227
- Sidekiq.logger = @old_logger
228
- Sidekiq.options.delete(:logfile)
229
- File.unlink @tmp_log_path if File.exist?(@tmp_log_path)
230
- end
231
-
232
- class CustomWorkerWithoutException
233
- include Sidekiq::Worker
234
-
235
- sidekiq_retry_in do |count|
236
- count * 2
237
- end
238
- end
239
-
240
- class CustomWorkerWithException
241
- include Sidekiq::Worker
242
-
243
- sidekiq_retry_in do |count, exception|
244
- case exception
245
- when ArgumentError
246
- count * 4
247
- else
248
- count * 2
249
- end
250
- end
251
- end
252
-
253
- class ErrorWorker
254
- include Sidekiq::Worker
255
-
256
- sidekiq_retry_in do |count|
257
- count / 0
258
- end
259
- end
260
-
261
- it "retries with a default delay" do
262
- refute_equal 4, handler.__send__(:delay_for, worker, 2, StandardError.new)
263
- end
264
-
265
- it "retries with a custom delay and exception 1" do
266
- assert_equal 8, handler.__send__(:delay_for, CustomWorkerWithException, 2, ArgumentError.new)
267
- end
268
-
269
- it "retries with a custom delay and exception 2" do
270
- assert_equal 4, handler.__send__(:delay_for, CustomWorkerWithException, 2, StandardError.new)
271
- end
272
-
273
- it "retries with a custom delay without exception" do
274
- assert_equal 4, handler.__send__(:delay_for, CustomWorkerWithoutException, 2, StandardError.new)
275
- end
276
-
277
- it "falls back to the default retry on exception" do
278
- refute_equal 4, handler.__send__(:delay_for, ErrorWorker, 2, StandardError.new)
279
- assert_match(/Failure scheduling retry using the defined `sidekiq_retry_in`/,
280
- File.read(@tmp_log_path), 'Log entry missing for sidekiq_retry_in')
281
- end
282
- end
283
-
284
- describe 'handles errors withouth cause' do
285
- before do
286
- @error = nil
287
- begin
288
- raise ::StandardError, 'Error'
289
- rescue ::StandardError => e
290
- @error = e
291
- end
292
- end
293
-
294
- it "does not recurse infinitely checking if it's a shutdown" do
295
- assert(!Sidekiq::Middleware::Server::RetryJobs.new.send(
296
- :exception_caused_by_shutdown?, @error))
297
- end
298
- end
299
-
300
- describe 'handles errors with circular causes' do
301
- before do
302
- @error = nil
303
- begin
304
- begin
305
- raise ::StandardError, 'Error 1'
306
- rescue ::StandardError => e1
307
- begin
308
- raise ::StandardError, 'Error 2'
309
- rescue ::StandardError
310
- raise e1
311
- end
312
- end
313
- rescue ::StandardError => e
314
- @error = e
315
- end
316
- end
317
-
318
- it "does not recurse infinitely checking if it's a shutdown" do
319
- assert(!Sidekiq::Middleware::Server::RetryJobs.new.send(
320
- :exception_caused_by_shutdown?, @error))
321
- end
322
- end
323
- end
324
-
325
- end