Skip to content

Commit 6620165

Browse files
committed
feat: Add retries to verification publishing
1 parent 8a0a73f commit 6620165

File tree

3 files changed

+55
-4
lines changed

3 files changed

+55
-4
lines changed

lib/pact/provider/verification_results/publish.rb

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
require 'json'
22
require 'pact/errors'
3+
require 'pact/retry'
34

45
# TODO move this to the pact broker client
56
# TODO retries
@@ -75,8 +76,10 @@ def tag_versions
7576
response = nil
7677
begin
7778
options = {:use_ssl => uri.scheme == 'https'}
78-
response = Net::HTTP.start(uri.host, uri.port, options) do |http|
79-
http.request request
79+
Retry.until_true do
80+
response = Net::HTTP.start(uri.host, uri.port, options) do |http|
81+
http.request request
82+
end
8083
end
8184
rescue StandardError => e
8285
error_message = "Failed to tag provider version due to: #{e.class} #{e.message}"
@@ -95,8 +98,10 @@ def publish_verification_results
9598
response = nil
9699
begin
97100
options = {:use_ssl => uri.scheme == 'https'}
98-
response = Net::HTTP.start(uri.host, uri.port, options) do |http|
99-
http.request request
101+
Retry.until_true do
102+
response = Net::HTTP.start(uri.host, uri.port, options) do |http|
103+
http.request request
104+
end
100105
end
101106
rescue StandardError => e
102107
error_message = "Failed to publish verification results due to: #{e.class} #{e.message}"

lib/pact/retry.rb

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
module Pact
2+
class Retry
3+
class RescuableError
4+
UNRESCUEABLE = [Pact::Error]
5+
6+
def self.===(e)
7+
case e
8+
when *UNRESCUEABLE then
9+
false
10+
else
11+
true
12+
end
13+
end
14+
end
15+
16+
def self.until_true options = {}
17+
max_tries = options.fetch(:times, 3)
18+
tries = 0
19+
while true
20+
begin
21+
return yield
22+
rescue RescuableError => e
23+
tries += 1
24+
$stderr.puts "Error making request - #{e.class} #{e.message} #{e.backtrace.find {|l| l.include?('pact_provider')}}, attempt #{tries} of #{max_tries}"
25+
raise e if max_tries == tries
26+
sleep options
27+
end
28+
end
29+
end
30+
31+
def self.sleep options
32+
Kernel.sleep options.fetch(:sleep, 5)
33+
end
34+
end
35+
end

spec/lib/pact/provider/verification_results/publish_spec.rb

+11
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ module VerificationResults
5454
allow(Pact.configuration).to receive(:provider).and_return(provider_configuration)
5555
stub_request(:post, stubbed_publish_verification_url).to_return(status: 200, body: created_verification_body)
5656
stub_request(:put, 'http://broker/pacticipants/Bar/versions/1.2.3/tags/foo')
57+
allow(Retry).to receive(:until_true) { |&block| block.call }
5758
end
5859

5960
subject { Publish.call(pact_source, verification) }
@@ -76,6 +77,11 @@ module VerificationResults
7677
expect(WebMock).to have_requested(:post, publish_verification_url).with(body: verification_json, headers: {'Content-Type' => 'application/json'})
7778
end
7879

80+
it "should call Retry.until_true once" do
81+
subject
82+
expect(Retry).to have_received(:until_true).once()
83+
end
84+
7985
context "when the verification result is not publishable" do
8086
let(:publishable) { false }
8187

@@ -93,6 +99,11 @@ module VerificationResults
9399
expect(WebMock).to have_requested(:put, 'http://broker/pacticipants/Bar/versions/1.2.3/tags/foo').with(headers: {'Content-Type' => 'application/json'})
94100
end
95101

102+
it "should call Retry.until_true twice" do
103+
subject
104+
expect(Retry).to have_received(:until_true).twice()
105+
end
106+
96107
context "when there is no pb:publish-verification-results link" do
97108
before do
98109
pact_hash['_links'].delete('pb:publish-verification-results')

0 commit comments

Comments
 (0)