From fd5651e9d8cee65d0f2d8df66ebf4809f6857b42 Mon Sep 17 00:00:00 2001 From: "Makarov.Dmitriy9" Date: Thu, 19 Sep 2019 15:28:51 +0300 Subject: [PATCH 1/6] fix grpc proxy --- etcd3/client.py | 61 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/etcd3/client.py b/etcd3/client.py index 5c7c7d20..c4780ef9 100644 --- a/etcd3/client.py +++ b/etcd3/client.py @@ -1,6 +1,7 @@ import functools import inspect import threading +import time import grpc import grpc._channel @@ -24,6 +25,40 @@ } +# this is used for gRPC proxy compatibility so that we do not +# mark as finished writing until we've received a response +# For more details see: https://github.com/davissp14/etcdv3-ruby/pull/117 +class BlockingRequest: + def __init__(self, request): + self.request = request + self.proceed = False + self.blocked = False + self.returned = False + + def read_done(self): + self.proceed = True + + def is_blocked(self): + return self.blocked + + def __iter__(self): + return self + + def __next__(self): + if not self.returned: + self.returned = True + return self.request + self.blocked = True + try: + raise StopIteration + except StopIteration: + raise StopIteration from None + finally: + while not self.proceed: + time.sleep(0.001) + self.blocked = False + + def _translate_exception(exc): code = exc.code() exception = _EXCEPTIONS_BY_CODE.get(code) @@ -898,14 +933,24 @@ def revoke_lease(self, lease_id): @_handle_errors def refresh_lease(self, lease_id): - keep_alive_request = etcdrpc.LeaseKeepAliveRequest(ID=lease_id) - request_stream = [keep_alive_request] - for response in self.leasestub.LeaseKeepAlive( - iter(request_stream), - self.timeout, - credentials=self.call_credentials, - metadata=self.metadata): - yield response + request_stream = BlockingRequest( + etcdrpc.LeaseKeepAliveRequest(ID=lease_id)) + responses = [] + try: + for response in self.leasestub.LeaseKeepAlive( + request_stream, + self.timeout, + credentials=self.call_credentials, + metadata=self.metadata): + responses.append(response) + break + except BaseException: + raise + finally: + request_stream.read_done() + while request_stream.is_blocked(): + time.sleep(0.001) + yield from responses @_handle_errors def get_lease_info(self, lease_id): From c74517b81e74e630e9e7ce5a07bda988f47c00ca Mon Sep 17 00:00:00 2001 From: "Makarov.Dmitriy9" Date: Fri, 20 Sep 2019 09:37:08 +0300 Subject: [PATCH 2/6] change patch version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 110578db..5f546f2f 100644 --- a/setup.py +++ b/setup.py @@ -25,7 +25,7 @@ def load_reqs(filename): setup( name='etcd3', - version='0.10.0', + version='0.10.1', description="Python client for the etcd3 API", long_description=readme + '\n\n' + history, author="Louis Taylor", From 189efb7eb197b539b23e287c99545259d72fb032 Mon Sep 17 00:00:00 2001 From: "Makarov.Dmitriy9" Date: Fri, 20 Sep 2019 10:52:14 +0300 Subject: [PATCH 3/6] add python2 compatibility --- etcd3/client.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/etcd3/client.py b/etcd3/client.py index c4780ef9..6fd9455b 100644 --- a/etcd3/client.py +++ b/etcd3/client.py @@ -52,12 +52,14 @@ def __next__(self): try: raise StopIteration except StopIteration: - raise StopIteration from None + raise StopIteration finally: while not self.proceed: time.sleep(0.001) self.blocked = False + next = __next__ # Python 2 compatibility + def _translate_exception(exc): code = exc.code() @@ -950,7 +952,9 @@ def refresh_lease(self, lease_id): request_stream.read_done() while request_stream.is_blocked(): time.sleep(0.001) - yield from responses + + for response in responses: + yield response @_handle_errors def get_lease_info(self, lease_id): From 1f61f955ebf997ce8da41145654e4f7f00b9b262 Mon Sep 17 00:00:00 2001 From: "Makarov.Dmitriy9" Date: Fri, 20 Sep 2019 11:01:12 +0300 Subject: [PATCH 4/6] flake8 requirements --- etcd3/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etcd3/client.py b/etcd3/client.py index 6fd9455b..0b25979d 100644 --- a/etcd3/client.py +++ b/etcd3/client.py @@ -58,7 +58,7 @@ def __next__(self): time.sleep(0.001) self.blocked = False - next = __next__ # Python 2 compatibility + next = __next__ # Python 2 compatibility def _translate_exception(exc): From d879629ccce793c64bfde2254b7f77fb3ae58ff5 Mon Sep 17 00:00:00 2001 From: "Makarov.Dmitriy9" Date: Sat, 21 Sep 2019 12:08:56 +0300 Subject: [PATCH 5/6] test for py36 --- test-requirements.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test-requirements.txt b/test-requirements.txt index c2e1b375..fedcf77e 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,16 +1,16 @@ PyYAML==5.1 Sphinx==1.8.2 bumpversion==0.5.3 -coverage==4.5.1 +coverage flake8-import-order==0.18 -flake8==3.6.0 +flake8 grpcio-tools>=1.2.0 -hypothesis==3.82.1 +hypothesis pip==18.1 pytest==4.0.1 wheel==0.31.1 -pycodestyle==2.4.0 +pycodestyle tox==3.5.3 -flake8-docstrings==1.3.0 +flake8-docstrings mock==2.0.0 pifpaf>=0.27.1 From 796cff9db0d936444500bf3423806f6c77c3404e Mon Sep 17 00:00:00 2001 From: "Makarov.Dmitriy9" Date: Sat, 21 Sep 2019 22:26:56 +0300 Subject: [PATCH 6/6] freeze versions --- test-requirements.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test-requirements.txt b/test-requirements.txt index fedcf77e..65221cf5 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,16 +1,16 @@ PyYAML==5.1 Sphinx==1.8.2 bumpversion==0.5.3 -coverage +coverage==4.5.4 flake8-import-order==0.18 -flake8 +flake8==3.7.8 grpcio-tools>=1.2.0 -hypothesis +hypothesis==4.36.2 pip==18.1 pytest==4.0.1 wheel==0.31.1 -pycodestyle +pycodestyle==2.5.0 tox==3.5.3 -flake8-docstrings +flake8-docstrings==1.4.0 mock==2.0.0 pifpaf>=0.27.1