Add auto retry logic for auth expiry separate from normal failure retry

This commit is contained in:
Doug Henderson 2014-03-13 11:20:08 -07:00
parent bfa5225766
commit 2bed0748ab
3 changed files with 33 additions and 17 deletions

View File

@ -114,6 +114,8 @@ in the credentials. Detailed instructions on how to enable delegation for your d
The API client can automatically retry requests for recoverable errors. To enable retries, set the `client.retries` property to The API client can automatically retry requests for recoverable errors. To enable retries, set the `client.retries` property to
the number of additional attempts. To avoid flooding servers, retries invovle a 1 second delay that increases on each subsequent retry. the number of additional attempts. To avoid flooding servers, retries invovle a 1 second delay that increases on each subsequent retry.
In the case of authentication token expiry, the API client will attempt to refresh the token and retry the failed operation - this
is a specific exception to the retry rules.
The default value for retries is 0, but will be enabled by default in future releases. The default value for retries is 0, but will be enabled by default in future releases.

View File

@ -596,6 +596,12 @@ module Google
Retriable.retriable :tries => tries, Retriable.retriable :tries => tries,
:on => [TransmissionError], :on => [TransmissionError],
:interval => lambda {|attempts| (2 ** attempts) + rand} do
# This 2nd level retriable only catches auth errors, and supports 1 retry, which allows
# auth to be re-attempted without having to retry all sorts of other failures like
# NotFound, etc
Retriable.retriable :tries => 2,
:on => [AuthorizationError],
:on_retry => client_error_handler(request.authorization), :on_retry => client_error_handler(request.authorization),
:interval => lambda {|attempts| (2 ** attempts) + rand} do :interval => lambda {|attempts| (2 ** attempts) + rand} do
result = request.send(connection, true) result = request.send(connection, true)
@ -609,7 +615,9 @@ module Google
:api_method => nil :api_method => nil
})) }))
raise RedirectError.new(result.headers['location'], result) raise RedirectError.new(result.headers['location'], result)
when 400...500 when 401
raise AuthorizationError.new(result.error_message || 'Invalid/Expired Authentication', result)
when 400, 402...500
raise ClientError.new(result.error_message || "A client error has occurred", result) raise ClientError.new(result.error_message || "A client error has occurred", result)
when 500...600 when 500...600
raise ServerError.new(result.error_message || "A server error has occurred", result) raise ServerError.new(result.error_message || "A server error has occurred", result)
@ -618,6 +626,7 @@ module Google
end end
end end
end end
end
## ##
# Same as Google::APIClient#execute!, but does not raise an exception for # Same as Google::APIClient#execute!, but does not raise an exception for

View File

@ -43,6 +43,11 @@ module Google
class ClientError < TransmissionError class ClientError < TransmissionError
end end
##
# A 401 HTTP error occurred.
class AuthorizationError < ClientError
end
## ##
# A 5xx class HTTP error occurred. # A 5xx class HTTP error occurred.
class ServerError < TransmissionError class ServerError < TransmissionError