Skip to content

Commit

Permalink
Retry wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
joecorcoran authored and vitalie committed Mar 28, 2023
1 parent 4014a03 commit 443c1bd
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 1 deletion.
1 change: 1 addition & 0 deletions lib/gh.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module GH
autoload :Normalizer, 'gh/normalizer'
autoload :Pagination, 'gh/pagination'
autoload :Parallel, 'gh/parallel'
autoload :Retry, 'gh/retry'
autoload :Remote, 'gh/remote'
autoload :Response, 'gh/response'
autoload :ResponseXHeaderFormatter, 'gh/response_x_header_formatter'
Expand Down
41 changes: 41 additions & 0 deletions lib/gh/retry.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require 'gh'

module GH
# Public: In some cases, the GitHub API can take some number of
# seconds to reflect a change in the system. This class catches 404
# responses for any GET request and retries the request.
class Retry < Wrapper
DEFAULTS = {
retries: 5,
wait: 1
}

attr_accessor :retries, :wait

def initialize(backend = nil, options = {})
options = DEFAULTS.merge options
super backend, options
end

def fetch_resource(key)
begin
decrement_retries!
super key
rescue GH::Error(response_status: 404) => e
retries_remaining? or raise e
sleep wait
fetch_resource key
end
end

private

def decrement_retries!
self.retries = self.retries - 1
end

def retries_remaining?
retries > 0
end
end
end
28 changes: 28 additions & 0 deletions spec/retry_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
require 'spec_helper'

describe GH::Retry do
let(:not_finder) do
Class.new(GH::MockBackend) do
def fetch_resource(key)
if key =~ %r{users/not-found}
@requests << key
error = Struct.new(:info).new(response_status: 404)
raise GH::Error.new(error)
end
super(key)
end
end
end

subject { described_class.new(not_finder.new, retries: 3, wait: 0.1) }

it 'retries request specified number of times' do
expect { subject['users/not-found'] }.to raise_error(GH::Error)
expect(subject.backend.requests.count).to eq 3
end

it 'does not retry when response is successful' do
subject['users/rkh']
expect(subject.backend.requests.count).to eq 1
end
end
2 changes: 1 addition & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def fetch_resource(key)
key_fn = sanitize_filename(key)
file = File.expand_path("../payloads/#{key_fn}.yml", __FILE__)
@requests << key
result = @data[key] ||= begin
result = @data[key] ||= begin
unless File.exist? file
res = allow_http { super }
FileUtils.mkdir_p File.dirname(file)
Expand Down

0 comments on commit 443c1bd

Please sign in to comment.