@@ -118,11 +118,13 @@ def perform
118118 expect ( job . polling_interval_seconds ) . to eq ( 24 . hours )
119119 end
120120
121- context 'exponential backoff rate' do
122- context 'updates the polling interval ' do
123- it 'when changing exponential backoff rate only' do
121+ describe 'exponential backoff rate' do
122+ context 'when changing exponential backoff rate only ' do
123+ before do
124124 TestConfig . config [ :broker_client_async_poll_exponential_backoff_rate ] = 2.0
125+ end
125126
127+ it 'updates the polling interval' do
126128 enqueued_time = 0
127129
128130 Timecop . freeze do
@@ -141,11 +143,15 @@ def perform
141143 end
142144 end
143145 end
146+ end
144147
145- it 'when changing exponential backoff rate and default polling interval' do
148+ context 'when changing exponential backoff rate and default polling interval' do
149+ before do
146150 TestConfig . config [ :broker_client_async_poll_exponential_backoff_rate ] = 1.3
147151 TestConfig . config [ :broker_client_default_async_poll_interval_seconds ] = 10
152+ end
148153
154+ it 'updates the polling interval' do
149155 enqueued_time = 0
150156
151157 Timecop . freeze do
@@ -164,36 +170,130 @@ def perform
164170 end
165171 end
166172 end
173+ end
167174
168- it 'when changing exponential backoff rate and retry_after from the job' do
169- TestConfig . config [ :broker_client_async_poll_exponential_backoff_rate ] = 1.3
170- TestConfig . config [ :broker_client_default_async_poll_interval_seconds ] = 10
175+ describe ' changing exponential backoff rate and retry_after from the job' do
176+ context 'when retry-after is larger than calculated backoff' do
177+ let ( :fake_job ) { FakeJob . new ( retry_after : [ 20 , 30 ] ) }
171178
172- enqueued_time = 0
179+ before do
180+ TestConfig . config [ :broker_client_async_poll_exponential_backoff_rate ] = 1.3
181+ TestConfig . config [ :broker_client_default_async_poll_interval_seconds ] = 10
182+ end
173183
174- Timecop . freeze do
175- Jobs ::Enqueuer . new ( queue : Jobs ::Queues . generic ) . enqueue_pollable ( FakeJob . new ( retry_after : [ 20 , 30 ] ) )
176- execute_all_jobs ( expected_successes : 1 , expected_failures : 0 )
177- enqueued_time = Time . now
184+ it 'uses retry-after interval' do
185+ enqueued_time = 0
186+
187+ Timecop . freeze do
188+ Jobs ::Enqueuer . new ( queue : Jobs ::Queues . generic ) . enqueue_pollable ( fake_job )
189+ execute_all_jobs ( expected_successes : 1 , expected_failures : 0 )
190+ enqueued_time = Time . now
191+ end
192+
193+ # the job should run after 20s (20s > 10 * 1.3^0)
194+ Timecop . freeze ( 19 . seconds . after ( enqueued_time ) ) do
195+ execute_all_jobs ( expected_successes : 0 , expected_failures : 0 )
196+ end
197+
198+ Timecop . freeze ( 21 . seconds . after ( enqueued_time ) ) do
199+ enqueued_time = Time . now
200+ execute_all_jobs ( expected_successes : 1 , expected_failures : 0 )
201+ end
202+
203+ # the job should run after 30s (30s > 10 * 1.3^1)
204+ Timecop . freeze ( 29 . seconds . after ( enqueued_time ) ) do
205+ execute_all_jobs ( expected_successes : 0 , expected_failures : 0 )
206+ end
207+
208+ Timecop . freeze ( 31 . seconds . after ( enqueued_time ) ) do
209+ execute_all_jobs ( expected_successes : 1 , expected_failures : 0 )
210+ end
178211 end
212+ end
179213
180- # the job should run after 20s * 1.3^0 = 20 seconds
181- Timecop . freeze ( 19 . seconds . after ( enqueued_time ) ) do
182- execute_all_jobs ( expected_successes : 0 , expected_failures : 0 )
214+ context 'when retry-after is smaller than calculated backoff' do
215+ let ( :fake_job ) { FakeJob . new ( retry_after : [ 10 , 20 ] ) }
216+
217+ before do
218+ TestConfig . config [ :broker_client_async_poll_exponential_backoff_rate ] = 1.3
219+ TestConfig . config [ :broker_client_default_async_poll_interval_seconds ] = 30
183220 end
184221
185- Timecop . freeze ( 21 . seconds . after ( enqueued_time ) ) do
186- enqueued_time = Time . now
187- execute_all_jobs ( expected_successes : 1 , expected_failures : 0 )
222+ it 'uses calculated interval' do
223+ enqueued_time = 0
224+
225+ Timecop . freeze do
226+ Jobs ::Enqueuer . new ( queue : Jobs ::Queues . generic ) . enqueue_pollable ( fake_job )
227+ execute_all_jobs ( expected_successes : 1 , expected_failures : 0 )
228+ enqueued_time = Time . now
229+ end
230+
231+ # the job should run after 30s (30s > 10s)
232+ Timecop . freeze ( 29 . seconds . after ( enqueued_time ) ) do
233+ execute_all_jobs ( expected_successes : 0 , expected_failures : 0 )
234+ end
235+
236+ Timecop . freeze ( 31 . seconds . after ( enqueued_time ) ) do
237+ enqueued_time = Time . now
238+ execute_all_jobs ( expected_successes : 1 , expected_failures : 0 )
239+ end
240+
241+ # the job should run after 30s (30s * 1.3^1 = 39 > 20s)
242+ Timecop . freeze ( 38 . seconds . after ( enqueued_time ) ) do
243+ execute_all_jobs ( expected_successes : 0 , expected_failures : 0 )
244+ end
245+
246+ Timecop . freeze ( 40 . seconds . after ( enqueued_time ) ) do
247+ execute_all_jobs ( expected_successes : 1 , expected_failures : 0 )
248+ end
188249 end
250+ end
189251
190- # the job should run after 30s * 1.3^1 = 39 seconds
191- Timecop . freeze ( 38 . seconds . after ( enqueued_time ) ) do
192- execute_all_jobs ( expected_successes : 0 , expected_failures : 0 )
252+ context 'when calculated backoff gets larger than retry-after' do
253+ let ( :fake_job ) { FakeJob . new ( retry_after : [ 15 , 15 , 15 ] ) }
254+
255+ before do
256+ TestConfig . config [ :broker_client_async_poll_exponential_backoff_rate ] = 2
257+ TestConfig . config [ :broker_client_default_async_poll_interval_seconds ] = 5
193258 end
194259
195- Timecop . freeze ( 40 . seconds . after ( enqueued_time ) ) do
196- execute_all_jobs ( expected_successes : 1 , expected_failures : 0 )
260+ it 'uses retry-after until calculated backoff is larger' do
261+ enqueued_time = 0
262+
263+ Timecop . freeze do
264+ Jobs ::Enqueuer . new ( queue : Jobs ::Queues . generic ) . enqueue_pollable ( fake_job )
265+ execute_all_jobs ( expected_successes : 1 , expected_failures : 0 )
266+ enqueued_time = Time . now
267+ end
268+
269+ # the job should run after 15s (15s > 5s (5 * 2^0))
270+ Timecop . freeze ( 14 . seconds . after ( enqueued_time ) ) do
271+ execute_all_jobs ( expected_successes : 0 , expected_failures : 0 )
272+ end
273+
274+ Timecop . freeze ( 16 . seconds . after ( enqueued_time ) ) do
275+ enqueued_time = Time . now
276+ execute_all_jobs ( expected_successes : 1 , expected_failures : 0 )
277+ end
278+
279+ # the job should run after 15s (15s > 10s (5 * 2^1))
280+ Timecop . freeze ( 14 . seconds . after ( enqueued_time ) ) do
281+ execute_all_jobs ( expected_successes : 0 , expected_failures : 0 )
282+ end
283+
284+ Timecop . freeze ( 16 . seconds . after ( enqueued_time ) ) do
285+ enqueued_time = Time . now
286+ execute_all_jobs ( expected_successes : 1 , expected_failures : 0 )
287+ end
288+
289+ # the job should run after 20s (20s > 15s (5 * 2^2))
290+ Timecop . freeze ( 19 . seconds . after ( enqueued_time ) ) do
291+ execute_all_jobs ( expected_successes : 0 , expected_failures : 0 )
292+ end
293+
294+ Timecop . freeze ( 21 . seconds . after ( enqueued_time ) ) do
295+ execute_all_jobs ( expected_successes : 1 , expected_failures : 0 )
296+ end
197297 end
198298 end
199299 end
0 commit comments