From 66201651af7b3ded75b19c3870c4e1632b969e92 Mon Sep 17 00:00:00 2001 From: Rashi Agarwal Date: Fri, 13 Apr 2018 14:14:46 +1000 Subject: [PATCH] feat: Add retries to verification publishing --- .../provider/verification_results/publish.rb | 13 ++++--- lib/pact/retry.rb | 35 +++++++++++++++++++ .../verification_results/publish_spec.rb | 11 ++++++ 3 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 lib/pact/retry.rb diff --git a/lib/pact/provider/verification_results/publish.rb b/lib/pact/provider/verification_results/publish.rb index e424c199..f73c68d7 100644 --- a/lib/pact/provider/verification_results/publish.rb +++ b/lib/pact/provider/verification_results/publish.rb @@ -1,5 +1,6 @@ require 'json' require 'pact/errors' +require 'pact/retry' # TODO move this to the pact broker client # TODO retries @@ -75,8 +76,10 @@ def tag_versions response = nil begin options = {:use_ssl => uri.scheme == 'https'} - response = Net::HTTP.start(uri.host, uri.port, options) do |http| - http.request request + Retry.until_true do + response = Net::HTTP.start(uri.host, uri.port, options) do |http| + http.request request + end end rescue StandardError => e error_message = "Failed to tag provider version due to: #{e.class} #{e.message}" @@ -95,8 +98,10 @@ def publish_verification_results response = nil begin options = {:use_ssl => uri.scheme == 'https'} - response = Net::HTTP.start(uri.host, uri.port, options) do |http| - http.request request + Retry.until_true do + response = Net::HTTP.start(uri.host, uri.port, options) do |http| + http.request request + end end rescue StandardError => e error_message = "Failed to publish verification results due to: #{e.class} #{e.message}" diff --git a/lib/pact/retry.rb b/lib/pact/retry.rb new file mode 100644 index 00000000..06a2f7fe --- /dev/null +++ b/lib/pact/retry.rb @@ -0,0 +1,35 @@ +module Pact + class Retry + class RescuableError + UNRESCUEABLE = [Pact::Error] + + def self.===(e) + case e + when *UNRESCUEABLE then + false + else + true + end + end + end + + def self.until_true options = {} + max_tries = options.fetch(:times, 3) + tries = 0 + while true + begin + return yield + rescue RescuableError => e + tries += 1 + $stderr.puts "Error making request - #{e.class} #{e.message} #{e.backtrace.find {|l| l.include?('pact_provider')}}, attempt #{tries} of #{max_tries}" + raise e if max_tries == tries + sleep options + end + end + end + + def self.sleep options + Kernel.sleep options.fetch(:sleep, 5) + end + end +end \ No newline at end of file diff --git a/spec/lib/pact/provider/verification_results/publish_spec.rb b/spec/lib/pact/provider/verification_results/publish_spec.rb index 8ef76666..ce5d26a5 100644 --- a/spec/lib/pact/provider/verification_results/publish_spec.rb +++ b/spec/lib/pact/provider/verification_results/publish_spec.rb @@ -54,6 +54,7 @@ module VerificationResults allow(Pact.configuration).to receive(:provider).and_return(provider_configuration) stub_request(:post, stubbed_publish_verification_url).to_return(status: 200, body: created_verification_body) stub_request(:put, 'http://broker/pacticipants/Bar/versions/1.2.3/tags/foo') + allow(Retry).to receive(:until_true) { |&block| block.call } end subject { Publish.call(pact_source, verification) } @@ -76,6 +77,11 @@ module VerificationResults expect(WebMock).to have_requested(:post, publish_verification_url).with(body: verification_json, headers: {'Content-Type' => 'application/json'}) end + it "should call Retry.until_true once" do + subject + expect(Retry).to have_received(:until_true).once() + end + context "when the verification result is not publishable" do let(:publishable) { false } @@ -93,6 +99,11 @@ module VerificationResults expect(WebMock).to have_requested(:put, 'http://broker/pacticipants/Bar/versions/1.2.3/tags/foo').with(headers: {'Content-Type' => 'application/json'}) end + it "should call Retry.until_true twice" do + subject + expect(Retry).to have_received(:until_true).twice() + end + context "when there is no pb:publish-verification-results link" do before do pact_hash['_links'].delete('pb:publish-verification-results')