Skip to content

Commit fbd29c0

Browse files
sfc-gh-abhatnagarsfc-gh-stakedasfc-gh-mkeller
authored
Prep 2.2.2 (#288)
* updated Python Connector reqs to branch * updated Python Connector reqs to branch master * SNOW-139744 bump idna and requests * updated Python Connector reqs to branch master * SNOW-141285 Fix a bug about not retrying in chunkdownloader * SNOW-132958 SNOW-104556 copied connector scripts into sub-directory and added py38 support * updated Python Connector reqs to branch master * SNOW-132958 SNOW-104556 fixed merge conflict * clean up * fixed script call * Bump up version to 2.2.2 * removed orig file * reverting build_inside_docker.sh removal * fixed permission issue * updated script call * removed period removal from install.sh Co-authored-by: Shige Takeda <[email protected]> Co-authored-by: Mark Keller <[email protected]>
1 parent 97cc99a commit fbd29c0

40 files changed

+1290
-81
lines changed

DESCRIPTION.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ Source code is also available at: https://github.com/snowflakedb/snowflake-conne
99
Release Notes
1010
-------------------------------------------------------------------------------
1111

12+
- v2.2.2(March 9,2020)
13+
14+
- Fix retry with chunck_downloader.py for stability.
15+
- Support Python 3.8 for Linux and Mac.
16+
1217
- v2.2.1(February 18,2020)
1318

1419
- Fix use DictCursor with execute_string #248

arrow_iterator.pyx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ cdef class PyArrowIterator(EmptyPyArrowIterator):
162162
cursor,
163163
OperationalError,
164164
{
165-
u'msg': u'Failed to open arrow stream: ' + ret.message(),
165+
u'msg': u'Failed to open arrow stream: ' + str(ret.message()),
166166
u'errno': ER_FAILED_TO_READ_ARROW_STREAM
167167
})
168168

@@ -174,7 +174,7 @@ cdef class PyArrowIterator(EmptyPyArrowIterator):
174174
cursor,
175175
OperationalError,
176176
{
177-
u'msg': u'Failed to read next arrow batch: ' + ret.message(),
177+
u'msg': u'Failed to read next arrow batch: ' + str(ret.message()),
178178
u'errno': ER_FAILED_TO_READ_ARROW_STREAM
179179
})
180180

chunk_downloader.py

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#
66

77
import json
8+
import time
89
from collections import namedtuple
910
from gzip import GzipFile
1011
from io import BytesIO
@@ -18,9 +19,9 @@
1819
from .arrow_context import ArrowConverterContext
1920
from .errorcode import ER_CHUNK_DOWNLOAD_FAILED
2021
from .errors import Error, OperationalError
21-
from .time_util import get_time_millis
22+
from .time_util import get_time_millis, DecorrelateJitterBackoff
2223

23-
DEFAULT_REQUEST_TIMEOUT = 3600
24+
DEFAULT_REQUEST_TIMEOUT = 7
2425

2526
DEFAULT_CLIENT_PREFETCH_THREADS = 4
2627
MAX_CLIENT_PREFETCH_THREADS = 10
@@ -113,41 +114,50 @@ def _download_chunk(self, idx):
113114
"""
114115
logger.debug(u'downloading chunk %s/%s', idx + 1, self._chunk_size)
115116
headers = {}
116-
try:
117-
if self._chunk_headers is not None:
118-
headers = self._chunk_headers
119-
logger.debug(u'use chunk headers from result')
120-
elif self._qrmk is not None:
121-
headers[SSE_C_ALGORITHM] = SSE_C_AES
122-
headers[SSE_C_KEY] = self._qrmk
123-
124-
logger.debug(u"started getting the result set %s: %s",
125-
idx + 1, self._chunks[idx].url)
126-
result_data = self._fetch_chunk(self._chunks[idx].url, headers)
127-
logger.debug(u"finished getting the result set %s: %s",
128-
idx + 1, self._chunks[idx].url)
129-
130-
if isinstance(result_data, ResultIterWithTimings):
131-
metrics = result_data.get_timings()
132-
with self._downloading_chunks_lock:
133-
self._total_millis_downloading_chunks += metrics[
134-
ResultIterWithTimings.DOWNLOAD]
135-
self._total_millis_parsing_chunks += metrics[
136-
ResultIterWithTimings.PARSE]
137-
138-
with self._chunk_cond:
139-
self._chunks[idx] = self._chunks[idx]._replace(
140-
result_data=result_data,
141-
ready=True)
142-
self._chunk_cond.notify_all()
143-
logger.debug(
144-
u'added chunk %s/%s to a chunk list.', idx + 1,
145-
self._chunk_size)
146-
except Exception as e:
147-
logger.exception(
148-
u'Failed to fetch the large result set chunk %s/%s',
149-
idx + 1, self._chunk_size)
150-
self._downloader_error = e
117+
if self._chunk_headers is not None:
118+
headers = self._chunk_headers
119+
logger.debug(u'use chunk headers from result')
120+
elif self._qrmk is not None:
121+
headers[SSE_C_ALGORITHM] = SSE_C_AES
122+
headers[SSE_C_KEY] = self._qrmk
123+
124+
last_error = None
125+
backoff = DecorrelateJitterBackoff(1, 16)
126+
sleep_timer = 1
127+
for retry in range(10):
128+
try:
129+
logger.debug(u"started getting the result set %s: %s",
130+
idx + 1, self._chunks[idx].url)
131+
result_data = self._fetch_chunk(self._chunks[idx].url, headers)
132+
logger.debug(u"finished getting the result set %s: %s",
133+
idx + 1, self._chunks[idx].url)
134+
135+
if isinstance(result_data, ResultIterWithTimings):
136+
metrics = result_data.get_timings()
137+
with self._downloading_chunks_lock:
138+
self._total_millis_downloading_chunks += metrics[
139+
ResultIterWithTimings.DOWNLOAD]
140+
self._total_millis_parsing_chunks += metrics[
141+
ResultIterWithTimings.PARSE]
142+
143+
with self._chunk_cond:
144+
self._chunks[idx] = self._chunks[idx]._replace(
145+
result_data=result_data,
146+
ready=True)
147+
self._chunk_cond.notify_all()
148+
logger.debug(
149+
u'added chunk %s/%s to a chunk list.', idx + 1,
150+
self._chunk_size)
151+
break
152+
except Exception as e:
153+
last_error = e
154+
sleep_timer = backoff.next_sleep(1, sleep_timer)
155+
logger.exception(
156+
u'Failed to fetch the large result set chunk %s/%s for the %s th time, backing off for %s s',
157+
idx + 1, self._chunk_size, retry + 1, sleep_timer)
158+
time.sleep(sleep_timer)
159+
else:
160+
self._downloader_error = last_error
151161

152162
def next_chunk(self):
153163
"""

docker/manylinux2010/Dockerfile-x86_64_base

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ RUN chmod +x /usr/local/bin/entrypoint.sh
1111

1212
WORKDIR /home/user
1313
RUN chmod 777 /home/user
14-
RUN git clone https://github.com/matthew-brett/multibuild.git && cd /home/user/multibuild && git checkout 1a7f31be677185f2dface2643284846e14130c3f
14+
RUN git clone https://github.com/matthew-brett/multibuild.git && cd /home/user/multibuild && git checkout b943f33a92772fd52c2fa38c03d08aac974c53bd
1515

1616
ADD scripts/build_virtualenvs.sh /home/user
1717
RUN /home/user/build_virtualenvs.sh

docker/manylinux2010/scripts/build_virtualenvs.sh

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,27 @@
1919
# Build upon the scripts in https://github.com/matthew-brett/manylinux-builds
2020
# * Copyright (c) 2013-2016, Matt Terry and Matthew Brett (BSD 2-clause)
2121

22-
PYTHON_VERSIONS="${PYTHON_VERSIONS:-35 36 37}"
22+
PYTHON_VERSIONS="${PYTHON_VERSIONS:-3.5 3.6 3.7 3.8}"
2323

2424
source /home/user/multibuild/manylinux_utils.sh
2525

2626
for PYTHON in ${PYTHON_VERSIONS}; do
2727
U_WIDTH=16
28-
PYTHON_INTERPRETER="$(cpython_path $PYTHON {U_WIDTH})/bin/python"
28+
PYTHON_INTERPRETER="$(cpython_path $PYTHON ${U_WIDTH})/bin/python"
2929
PIP="$(cpython_path $PYTHON ${U_WIDTH})/bin/pip"
3030
PATH="$PATH:$(cpython_path $PYTHON ${U_WIDTH})"
3131

32+
echo "=== Updating pip ==="
33+
$PIP install -U "pip"
34+
3235
echo "=== (${PYTHON}, ${U_WIDTH}) Installing build dependencies ==="
33-
$PIP install "virtualenv==16.3.0"
36+
$PIP install "virtualenv"
3437

3538
echo "=== (${PYTHON}, ${U_WIDTH}) Preparing virtualenv for build ==="
3639
"$(cpython_path $PYTHON ${U_WIDTH})/bin/virtualenv" -p ${PYTHON_INTERPRETER} --no-download /home/user/venv-build-${PYTHON}
3740
source /home/user/venv-build-${PYTHON}/bin/activate
38-
pip install "cython==0.29.8" "setuptools" "flake8" "wheel" "pyarrow==0.15.1"
41+
pip install -U pip
42+
pip install "cython==0.29.15" "setuptools" "flake8" "wheel" "pyarrow==0.16.0"
3943
deactivate
4044
done
4145

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# We use manylinux1 base image because pyarrow_manylinux2010 has a bug and wheel failed to be audited
2+
FROM quay.io/pypa/manylinux2010_x86_64
3+
4+
# This is to solve permission issue, read https://denibertovic.com/posts/handling-permissions-with-docker-volumes/
5+
RUN curl -o /usr/local/bin/gosu -SL "https://github.com/tianon/gosu/releases/download/1.11/gosu-amd64"
6+
RUN chmod +x /usr/local/bin/gosu
7+
8+
COPY scripts/entrypoint.sh /usr/local/bin/entrypoint.sh
9+
RUN chmod +x /usr/local/bin/entrypoint.sh
10+
11+
12+
WORKDIR /home/user
13+
RUN chmod 777 /home/user
14+
ENV PATH="${PATH}:/opt/python/cp35-cp35m/bin:/opt/python/cp36-cp36m/bin:/opt/python/cp37-cp37m/bin:/opt/python/cp38-cp38/bin/"
15+
16+
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/bash
2+
3+
# Add local user
4+
# Either use the LOCAL_USER_ID if passed in at runtime or
5+
# fallback
6+
7+
USER_ID=${LOCAL_USER_ID:-9001}
8+
9+
echo "Starting with UID : $USER_ID"
10+
useradd --shell /bin/bash -u $USER_ID -o -c "" -m user
11+
export HOME=/home/user
12+
13+
/usr/local/bin/gosu user "$@"

scripts/anaconda/bld.bat

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
$PYTHON setup.py install

scripts/anaconda/build.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
$PYTHON setup.py install --single-version-externally-managed --record=record.txt

scripts/anaconda/meta.yaml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package:
2+
name: snowflake_connector_python
3+
version: "1.2.3"
4+
5+
source:
6+
path: /tmp/anaconda_workspace/src
7+
8+
requirements:
9+
build:
10+
- python
11+
- setuptools
12+
13+
run:
14+
- python
15+
- boto3 ==1.3.1
16+
- botocore ==1.4.26
17+
- future
18+
- six
19+
- pytz
20+
- pycrypto ==2.6.1
21+
- pyopenssl ==0.15.1
22+
- cryptography ==1.2.3
23+
- cffi ==1.6.0
24+
25+
about:
26+
home: https://www.snowflake.net/
27+
license: Apache 2.0
28+
license_file: /tmp/anaconda_workspace/src/LICENSE.txt
29+
summary: Snowflake Connector for Python

0 commit comments

Comments
 (0)