Skip to content

Commit c44a2c0

Browse files
committed
SNOW-27430: added retry for BAD_GATEWAY and increased the retry counter
1 parent fa423ec commit c44a2c0

File tree

5 files changed

+37
-15
lines changed

5 files changed

+37
-15
lines changed

compat.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
PKCS5_OFFSET = lambda v: ord(v[-1])
4343
IS_BINARY = lambda v: isinstance(v, bytearray)
4444

45+
BAD_GATEWAY = httplib.BAD_GATEWAY
4546
BAD_REQUEST = httplib.BAD_REQUEST
4647
SERVICE_UNAVAILABLE = httplib.SERVICE_UNAVAILABLE
4748
GATEWAY_TIMEOUT = httplib.GATEWAY_TIMEOUT
@@ -74,6 +75,7 @@
7475
PKCS5_OFFSET = lambda v: v[-1]
7576
IS_BINARY = lambda v: isinstance(v, (bytes, bytearray))
7677

78+
BAD_GATEWAY = http.client.BAD_GATEWAY
7779
BAD_REQUEST = http.client.BAD_REQUEST
7880
SERVICE_UNAVAILABLE = http.client.SERVICE_UNAVAILABLE
7981
GATEWAY_TIMEOUT = http.client.GATEWAY_TIMEOUT

connection.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,11 +559,12 @@ def _cmd_query(self, sql, sequence_counter, request_id,
559559

560560
url_parameters = {u'requestId': request_id}
561561

562+
# retry 1000 times/4.5 hours for general queries
562563
ret = self._con.request(
563564
u'/queries/v1/query-request?' + urlencode(url_parameters),
564565
data,
565566
client=client,
566-
_no_results=_no_results)
567+
_no_results=_no_results, retry=1000)
567568

568569
if ret is not None and u'data' in ret and ret[u'data'] is None:
569570
ret[u'data'] = {}

cursor.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,9 @@ def chunk_info(self, data, use_ijson=False):
578578

579579
def query_result(self, qid, _use_ijson=False):
580580
url = ('/queries/{qid}/result').format(qid=qid)
581-
ret = self._connection._con.request(url=url, method='get')
581+
# retry 1000 times for getting the results
582+
ret = self._connection._con.request(
583+
url=url, method='get', retry=1000)
582584
if ret.get(u'success'):
583585
data = ret.get(u'data')
584586
self.chunk_info(data, use_ijson=_use_ijson)
@@ -602,7 +604,8 @@ def query_result(self, qid, _use_ijson=False):
602604

603605
def abort_query(self, qid):
604606
url = ('/queries/{qid}/abort-request').format(qid=qid)
605-
ret = self._connection._con.request(url=url, method='post')
607+
ret = self._connection._con.request(
608+
url=url, method='post', retry=100)
606609
return ret.get(u'success')
607610

608611
def executemany(self, command, seqparams):

errors.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,10 @@ class BadRequest(Error):
199199

200200
def __init__(self):
201201
Error.__init__(self, msg=u'HTTP 400: BadRequest')
202+
203+
204+
class BadGatewayError(Error):
205+
u"""Exception for 502 HTTP error for retry"""
206+
207+
def __init__(self):
208+
Error.__init__(self, msg=u'HTTP 502: BadGateway')

network.py

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from . import ssl_wrap_socket
2727
from .compat import (
2828
BAD_REQUEST, SERVICE_UNAVAILABLE, GATEWAY_TIMEOUT,
29-
FORBIDDEN,
29+
FORBIDDEN, BAD_GATEWAY,
3030
UNAUTHORIZED, INTERNAL_SERVER_ERROR, OK, BadStatusLine)
3131
from .compat import (Queue, EmptyQueue)
3232
from .compat import (TO_UNICODE, urlencode)
@@ -37,7 +37,7 @@
3737
from .errors import (Error, OperationalError, DatabaseError, ProgrammingError,
3838
GatewayTimeoutError, ServiceUnavailableError,
3939
InterfaceError, InternalServerError, ForbiddenError,
40-
BadRequest)
40+
BadGatewayError, BadRequest)
4141
from .gzip_decoder import (decompress_raw_data)
4242
from .sqlstate import (SQLSTATE_CONNECTION_NOT_EXISTS,
4343
SQLSTATE_CONNECTION_WAS_NOT_ESTABLISHED,
@@ -95,6 +95,7 @@
9595
SERVICE_UNAVAILABLE: ServiceUnavailableError,
9696
GATEWAY_TIMEOUT: GatewayTimeoutError,
9797
BAD_REQUEST: BadRequest,
98+
BAD_GATEWAY: BadGatewayError,
9899
}
99100

100101

@@ -295,7 +296,9 @@ def authenticate(self, account, user, password, master_token=None,
295296
"body['data']: %s",
296297
{k: v for (k, v) in body[u'data'].items() if k != u'PASSWORD'})
297298

298-
ret = self._post_request(url, headers, json.dumps(body))
299+
# retry 10 times for authentication
300+
ret = self._post_request(
301+
url, headers, json.dumps(body), retry=10)
299302
# this means we are waiting for MFA authentication
300303
if ret[u'data'].get(u'nextAction') and ret[u'data'][
301304
u'nextAction'] == u'EXT_AUTHN_DUO_ALL':
@@ -304,7 +307,8 @@ def authenticate(self, account, user, password, master_token=None,
304307
self.ret = None
305308

306309
def post_request_wrapper(self, url, headers, body):
307-
self.ret = self._post_request(url, headers, body)
310+
# retry 10 times for MFA approval
311+
self.ret = self._post_request(url, headers, body, retry=10)
308312

309313
# send new request to wait until MFA is approved
310314
t = Thread(target=post_request_wrapper,
@@ -316,14 +320,16 @@ def post_request_wrapper(self, url, headers, body):
316320
while not self.ret:
317321
next(c)
318322
else:
319-
t.join()
323+
t.join(timeout=120)
320324
ret = self.ret
321325
if ret[u'data'].get(u'nextAction') and ret[u'data'][
322326
u'nextAction'] == u'EXT_AUTHN_SUCCESS':
323327
body = copy.deepcopy(body_template)
324328
body[u'inFlightCtx'] = ret[u'data'][u'inFlightCtx']
325329
# final request to get tokens
326-
ret = self._post_request(url, headers, json.dumps(body))
330+
# retry 10 times
331+
ret = self._post_request(
332+
url, headers, json.dumps(body), retry=10)
327333

328334
elif ret[u'data'].get(u'nextAction') and ret[u'data'][
329335
u'nextAction'] == u'PWD_CHANGE':
@@ -333,7 +339,9 @@ def post_request_wrapper(self, url, headers, body):
333339
body[u'data'][u"LOGIN_NAME"] = user
334340
body[u'data'][u"PASSWORD"] = password
335341
body[u'data'][u'CHOSEN_NEW_PASSWORD'] = password_callback()
336-
ret = self._post_request(url, headers, json.dumps(body))
342+
# retry 10 times for New Password input
343+
ret = self._post_request(
344+
url, headers, json.dumps(body), retry=10)
337345

338346
self.logger.debug(u'completed authentication')
339347
if not ret[u'success']:
@@ -373,7 +381,7 @@ def post_request_wrapper(self, url, headers, body):
373381
self._connection._warehouse = session_info[u'warehouseName']
374382

375383
def request(self, url, body=None, method=u'post', client=u'sfsql',
376-
_no_results=False):
384+
_no_results=False, retry=10):
377385
if body is None:
378386
body = {}
379387
if not hasattr(self, u'_master_token'):
@@ -396,11 +404,12 @@ def request(self, url, body=None, method=u'post', client=u'sfsql',
396404
u"User-Agent": PYTHON_CONNECTOR_USER_AGENT,
397405
}
398406
if method == u'post':
399-
return self._post_request(url, headers, json.dumps(body),
400-
token=self._token,
401-
_no_results=_no_results)
407+
return self._post_request(
408+
url, headers, json.dumps(body),
409+
token=self._token, _no_results=_no_results, retry=retry)
402410
else:
403-
return self._get_request(url, headers, token=self._token)
411+
return self._get_request(
412+
url, headers, token=self._token, retry=retry)
404413

405414
def _renew_session(self):
406415
if not hasattr(self, u'_master_token'):

0 commit comments

Comments
 (0)