@@ -109,6 +109,7 @@ def initialize(options={})
109
109
self . key = options [ :key ]
110
110
self . user_ip = options [ :user_ip ]
111
111
self . retries = options . fetch ( :retries ) { 0 }
112
+ self . expired_auth_retry = options . fetch ( :expired_auth_retry ) { true }
112
113
@discovery_uris = { }
113
114
@discovery_documents = { }
114
115
@discovered_apis = { }
@@ -239,6 +240,13 @@ def authorization=(new_authorization)
239
240
# Number of retries
240
241
attr_accessor :retries
241
242
243
+ ##
244
+ # Whether or not an expired auth token should be re-acquired
245
+ # (and the operation retried) regardless of retries setting
246
+ # @return [Boolean]
247
+ # Auto retry on auth expiry
248
+ attr_accessor :expired_auth_retry
249
+
242
250
##
243
251
# Returns the URI for the directory document.
244
252
#
@@ -593,16 +601,20 @@ def execute!(*params)
593
601
request . authorization = options [ :authorization ] || self . authorization unless options [ :authenticated ] == false
594
602
595
603
tries = 1 + ( options [ :retries ] || self . retries )
604
+ attempt = 0
596
605
597
606
Retriable . retriable :tries => tries ,
598
607
:on => [ TransmissionError ] ,
608
+ :on_retry => client_error_handler ,
599
609
:interval => lambda { |attempts | ( 2 ** attempts ) + rand } do
610
+ attempt += 1
611
+
600
612
# This 2nd level retriable only catches auth errors, and supports 1 retry, which allows
601
613
# auth to be re-attempted without having to retry all sorts of other failures like
602
614
# NotFound, etc
603
- Retriable . retriable :tries => 2 ,
615
+ Retriable . retriable :tries => ( ( expired_auth_retry || tries > 1 ) && attempt == 1 ) ? 2 : 1 ,
604
616
:on => [ AuthorizationError ] ,
605
- :on_retry => client_error_handler ( request . authorization ) ,
617
+ :on_retry => authorization_error_handler ( request . authorization ) ,
606
618
:interval => lambda { |attempts | ( 2 ** attempts ) + rand } do
607
619
result = request . send ( connection , true )
608
620
@@ -671,18 +683,17 @@ def resolve_uri(template, mapping={})
671
683
672
684
673
685
##
674
- # Returns on proc for special processing of retries as not all client errors
675
- # are recoverable. Only 401s should be retried and only if the credentials
676
- # are refreshable
686
+ # Returns on proc for special processing of retries for authorization errors
687
+ # Only 401s should be retried and only if the credentials are refreshable
677
688
#
678
689
# @param [#fetch_access_token!] authorization
679
690
# OAuth 2 credentials
680
- # @return [Proc]
681
- def client_error_handler ( authorization )
691
+ # @return [Proc]
692
+ def authorization_error_handler ( authorization )
682
693
can_refresh = authorization . respond_to? ( :refresh_token ) && auto_refresh_token
683
694
Proc . new do |exception , tries |
684
- next unless exception . kind_of? ( ClientError )
685
- if exception . result . status == 401 && can_refresh && tries == 1
695
+ next unless exception . kind_of? ( AuthorizationError )
696
+ if can_refresh
686
697
begin
687
698
logger . debug ( "Attempting refresh of access token & retry of request" )
688
699
authorization . fetch_access_token!
@@ -694,6 +705,17 @@ def client_error_handler(authorization)
694
705
end
695
706
end
696
707
708
+ ##
709
+ # Returns on proc for special processing of retries as not all client errors
710
+ # are recoverable. Only 401s should be retried (via authorization_error_handler)
711
+ #
712
+ # @return [Proc]
713
+ def client_error_handler
714
+ Proc . new do |exception , tries |
715
+ raise exception if exception . kind_of? ( ClientError )
716
+ end
717
+ end
718
+
697
719
end
698
720
699
721
end
0 commit comments