@@ -3322,17 +3322,39 @@ def _call_rpc(self, method, params, include_auth_params=True, first=False):
33223322 if self .config .localized is True :
33233323 req_headers ["locale" ] = "auto"
33243324
3325- http_status , resp_headers , body = self ._make_call ("POST" , self .config .api_path ,
3326- encoded_payload , req_headers )
3327- LOG .debug ("Completed rpc call to %s" % (method ))
3328- try :
3329- self ._parse_http_status (http_status )
3330- except ProtocolError as e :
3331- e .headers = resp_headers
3332- # 403 is returned with custom error page when api access is blocked
3333- if e .errcode == 403 :
3334- e .errmsg += ": %s" % body
3335- raise
3325+ attempt = 1
3326+ max_attempts = 4 # Three retries on failure
3327+ backoff = 0.75 # Seconds to wait before retry, times the attempt number
3328+
3329+ while attempt <= max_attempts :
3330+ http_status , resp_headers , body = self ._make_call (
3331+ "POST" ,
3332+ self .config .api_path ,
3333+ encoded_payload ,
3334+ req_headers ,
3335+ )
3336+
3337+ LOG .debug ("Completed rpc call to %s" % (method ))
3338+
3339+ try :
3340+ self ._parse_http_status (http_status )
3341+ except ProtocolError as e :
3342+ e .headers = resp_headers
3343+
3344+ # We've seen some rare instances of SG returning 502 for issues that
3345+ # appear to be caused by something internal to SG. We're going to
3346+ # allow for limited retries for those specifically.
3347+ if attempt != max_attempts and e .errcode == 502 :
3348+ LOG .debug ("Got a 502 response. Waiting and retrying..." )
3349+ time .sleep (float (attempt ) * backoff )
3350+ attempt += 1
3351+ continue
3352+ elif e .errcode == 403 :
3353+ # 403 is returned with custom error page when api access is blocked
3354+ e .errmsg += ": %s" % body
3355+ raise
3356+ else :
3357+ break
33363358
33373359 response = self ._decode_response (resp_headers , body )
33383360 self ._response_errors (response )
0 commit comments