@@ -3322,17 +3322,39 @@ def _call_rpc(self, method, params, include_auth_params=True, first=False):
3322
3322
if self .config .localized is True :
3323
3323
req_headers ["locale" ] = "auto"
3324
3324
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
3336
3358
3337
3359
response = self ._decode_response (resp_headers , body )
3338
3360
self ._response_errors (response )
0 commit comments