Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Limit number of repetitions for retryable requests

If a RetryableAPIError exception is raised, we only repeat the request
MAX_RETRIES number of times before raising an APIError. This guards against
infinite loops, while still allowing most 403 errors to be worked around.

As I explained in the commit message for
6cae2e3, this logic is still pretty vague
because GitHub hasn't documented their rate limiting policy yet.
  • Loading branch information...
commit a26df884ed2ecfab18da7ec25c563b38467b84a6 1 parent 6cae2e3
@runpaint authored
Showing with 21 additions and 11 deletions.
  1. +16 −8 lib/octopi.rb
  2. +5 −3 lib/octopi/error.rb
View
24 lib/octopi.rb
@@ -66,6 +66,8 @@ class Api
'xml' => 'application/sml'
}
RETRYABLE_STATUS = [403]
+ MAX_RETRIES = 10
+
base_uri "http://github.com/api/v2"
attr_accessor :format, :login, :token, :trace_level, :read_only
@@ -147,7 +149,7 @@ def submit(path, params = {}, format = "yaml", &block)
resp = yield(path, query.merge(params), format)
rescue Net::HTTPBadResponse
raise RetryableAPIError
- end
+ end
if @trace_level
case @trace_level
@@ -174,14 +176,21 @@ def submit(path, params = {}, format = "yaml", &block)
end
def get(path, params = {}, format = "yaml")
- trace "GET [#{format}]", "/#{format}#{path}", params
+ @@retries = 0
begin
- submit(path, params, format) do |path, params, format|
- self.class.get "/#{format}#{path}"
- end
+ trace "GET [#{format}]", "/#{format}#{path}", params
+ submit(path, params, format) do |path, params, format|
+ self.class.get "/#{format}#{path}"
+ end
rescue RetryableAPIError => e
- $stderr.puts e.message
- retry
+ if @@retries < MAX_RETRIES
+ $stderr.puts e.message
+ @@retries += 1
+ retry
+ else
+ raise APIError, "GitHub returned status #{e.code}, despite" +
+ " repeating the request #{MAX_RETRIES} times. Giving up."
+ end
end
end
@@ -190,7 +199,6 @@ def trace(oper, url, params)
par_str = " params: " + params.map { |p| "#{p[0]}=#{p[1]}" }.join(", ") if params and !params.empty?
puts "#{oper}: #{url}#{par_str}"
end
- end
@fcoury
fcoury added a note

This end should have stayed :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
%w{error base resource user tag repository issue file_object blob commit branch}.
each{|f| require "#{File.dirname(__FILE__)}/octopi/#{f}"}
View
8 lib/octopi/error.rb
@@ -13,9 +13,11 @@ def initialize(m)
end
class RetryableAPIError < RuntimeError
- def initalize(status=nil)
- $stderr.puts "GitHub returned status #{status.nil? ? '???' : status}. Retrying request."
+ attr_reader :code
+ def initialize(code=nil)
+ @code = code.nil? ? '???' : code
+ @message = "GitHub returned status #{@code}. Retrying request."
+ super @message
end
end
-
end
Please sign in to comment.
Something went wrong with that request. Please try again.