Skip to content
This repository was archived by the owner on Jun 2, 2021. It is now read-only.

Commit e8ccc8e

Browse files
blgmBrian Butz
andauthored
v3(services): route binding respect Retry-After header (cloudfoundry#1811)
* v3(services): route binding respect Retry-After header [#174398274](https://www.pivotaltracker.com/story/show/174398274) * Refactor tuple return to Complete/NotComplete types Co-authored-by: Brian Butz <bbutz@pivotal.io>
1 parent fefb47f commit e8ccc8e

4 files changed

Lines changed: 68 additions & 9 deletions

File tree

app/actions/service_route_binding_create.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,17 +70,24 @@ def poll(binding)
7070
record_audit_event(binding)
7171
end
7272

73-
binding.reload.terminal_state?
73+
if binding.reload.terminal_state?
74+
PollingComplete.new
75+
else
76+
PollingNotComplete.new(details[:retry_after])
77+
end
7478
rescue => e
7579
binding.save_with_new_operation({}, {
7680
type: 'create',
7781
state: 'failed',
7882
description: e.message,
7983
})
8084

81-
true
85+
return PollingComplete.new
8286
end
8387

88+
PollingComplete = Class.new.freeze
89+
PollingNotComplete = Struct.new(:retry_after).freeze
90+
8491
class UnprocessableCreate < StandardError; end
8592

8693
class RouteBindingAlreadyExists < StandardError; end

app/jobs/v3/create_route_binding_job.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,15 @@ def perform
4848
return finish if precursor.reload.terminal_state?
4949
end
5050

51-
complete = action.poll(precursor)
52-
finish if complete
51+
polling_status = action.poll(precursor)
52+
case polling_status
53+
when ServiceRouteBindingCreate::PollingComplete
54+
finish
55+
when ServiceRouteBindingCreate::PollingNotComplete
56+
unless polling_status.retry_after.nil?
57+
self.polling_interval_seconds = polling_status.retry_after
58+
end
59+
end
5360
end
5461

5562
private

spec/unit/actions/service_route_binding_create_spec.rb

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,8 @@ class BadError < StandardError; end
335335
end
336336

337337
it 'returns true' do
338-
expect(action.poll(binding)).to be_truthy
338+
polling_status = action.poll(binding)
339+
expect(polling_status).to be_a_kind_of(ServiceRouteBindingCreate::PollingComplete)
339340
end
340341

341342
it 'updates the last operation' do
@@ -407,7 +408,8 @@ class BadError < StandardError; end
407408

408409
context 'response says in progress' do
409410
it 'returns false' do
410-
expect(action.poll(binding)).to be_falsey
411+
polling_status = action.poll(binding)
412+
expect(polling_status).to be_a_kind_of(ServiceRouteBindingCreate::PollingNotComplete)
411413
end
412414

413415
it 'updates the last operation' do
@@ -430,7 +432,8 @@ class BadError < StandardError; end
430432
let(:state) { 'failed' }
431433

432434
it 'returns true' do
433-
expect(action.poll(binding)).to be_truthy
435+
polling_status = action.poll(binding)
436+
expect(polling_status).to be_a_kind_of(ServiceRouteBindingCreate::PollingComplete)
434437
end
435438

436439
it 'updates the last operation' do
@@ -448,6 +451,33 @@ class BadError < StandardError; end
448451
expect(event_repository).not_to have_received(:record_service_instance_event)
449452
end
450453
end
454+
455+
context 'retry interval' do
456+
context 'no retry interval' do
457+
it 'returns nil' do
458+
polling_status = action.poll(binding)
459+
expect(polling_status.retry_after).to be_nil
460+
end
461+
end
462+
463+
context 'retry interval specified' do
464+
let(:fetch_last_operation_response) do
465+
{
466+
last_operation: {
467+
state: state,
468+
description: description,
469+
},
470+
retry_after: 10,
471+
}
472+
end
473+
474+
it 'returns the value when there was a retry header' do
475+
polling_status = action.poll(binding)
476+
expect(polling_status).to be_a_kind_of(ServiceRouteBindingCreate::PollingNotComplete)
477+
expect(polling_status.retry_after).to eq(10)
478+
end
479+
end
480+
end
451481
end
452482
end
453483
end

spec/unit/jobs/v3/create_route_binding_job_spec.rb

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ module V3
3535
end
3636

3737
describe '#perform' do
38-
let(:poll_response) { false }
38+
let(:poll_response) { ServiceRouteBindingCreate::PollingNotComplete.new(nil) }
3939
let(:action) do
4040
instance_double(V3::ServiceRouteBindingCreate, {
4141
bind: nil,
@@ -116,7 +116,7 @@ module V3
116116
end
117117

118118
context 'poll indicates binding complete' do
119-
let(:poll_response) { true }
119+
let(:poll_response) { ServiceRouteBindingCreate::PollingComplete.new }
120120

121121
it 'finishes the job' do
122122
subject.perform
@@ -125,6 +125,21 @@ module V3
125125
end
126126
end
127127
end
128+
129+
context 'retry interval' do
130+
def test_retry_after(value, expected)
131+
allow(action).to receive(:poll).and_return(ServiceRouteBindingCreate::PollingNotComplete.new(value))
132+
subject.perform
133+
expect(subject.polling_interval_seconds).to eq(expected)
134+
end
135+
136+
it 'updates the polling interval' do
137+
test_retry_after(10, 60) # below default
138+
test_retry_after(65, 65)
139+
test_retry_after(1.hour, 1.hour)
140+
test_retry_after(25.hours, 24.hours) # above limit
141+
end
142+
end
128143
end
129144

130145
describe '#operation' do

0 commit comments

Comments
 (0)