** Also affects: python-etcd3gw (Ubuntu)
Importance: Undecided
Status: New
** Also affects: python-etcd3gw (Ubuntu Jammy)
Importance: Undecided
Status: New
** Also affects: python-etcd3gw (Ubuntu Noble)
Importance: Undecided
Status: New
** Also affects: python-etcd3gw (Ubuntu Oracular)
Importance: Undecided
Status: New
** Changed in: python-etcd3gw (Ubuntu)
Status: New => Fix Released
** Changed in: python-etcd3gw (Ubuntu Jammy)
Status: New => In Progress
** Changed in: python-etcd3gw (Ubuntu Noble)
Status: New => In Progress
** Changed in: python-etcd3gw (Ubuntu Oracular)
Status: New => In Progress
** Changed in: python-etcd3gw (Ubuntu Jammy)
Assignee: (unassigned) => Wesley Hershberger (whershberger)
** Changed in: python-etcd3gw (Ubuntu Noble)
Assignee: (unassigned) => Wesley Hershberger (whershberger)
** Changed in: python-etcd3gw (Ubuntu Oracular)
Assignee: (unassigned) => Wesley Hershberger (whershberger)
** Tags added: sts
** Description changed:
+ [ Impact ]
+ The current `Etcd3Client` object attempts to set the `timeout` attribute of
its requests.Session; requests.Session does not reference `timeout` [1] so the
current behavior is a no-op.
+
+ If a caller of `Etcd3Client` makes requests in a loop (expecting dropped
+ requests to time out), a failed/dropped request may block the loop. An
+ affected user was performing etcd compaction [2] in such a loop; without
+ periodic compaction requests the cluster filled its quota and became
+ unavailable for writes.
+
+ This fix was released in 2.4.0 and is present in Plucky+ [4].
+
+ I've included a small patch to allow the package's unittests to pass in
+ Noble/Oracular.
+
+ [1] https://requests.readthedocs.io/en/latest/api/#requests.Session
+ [2]
https://etcd.io/docs/v3.5/op-guide/maintenance/#history-compaction-v3-api-key-value-database
+ [3] https://etcd.io/docs/v3.5/op-guide/maintenance/#space-quota
+ [4]
https://opendev.org/openstack/etcd3gw/commit/04c7907854bdc66c85147f79058732ed4828e960
+
+ [ Test Plan ]
+
+ ```
+ cat >timeout.py<<EOF
+ import etcd3gw
+ client = etcd3gw.Etcd3Client(timeout=1)
+ resp = client.post("https://httpbin.org/delay/10")
+ print(resp.status_code)
+ EOF
+ python3 timeout.py
+ ```
+
+ Expected Result:
+ ```
+ etcd3gw.exceptions.ConnectionTimeoutError
+ ```
+
+ Observed Result:
+ ```
+ 200
+ ```
+
+ Alternatively, use `https://10.255.255.255/` if httpbin is giving 503s.
+
+ [ Regression Test ]
+
+ Install etcd:
+ ```
+ sudo apt-get install etcd-server etcd-client
+ ```
+
+ In Jammy:
+ ```
+ etcdctl --debug cluster-health # expect "cluster is healthy"
+ ```
+
+ In Noble+:
+ ```
+ etcdctl --debug endpoint health # expect "127.0.0.1:2379 is healthy"
+ ```
+
+ Run the unittests to verify that requests function as expected:
+ ```
+ git-ubuntu clone python-etcd3gw
+ cd python-etcd3gw && git switch ubuntu/jammy-proposed
+ sudo apt build-dep .
+ quilt push -a
+ debuild -us -uc
+ ```
+
+ There is one expected unittest failure in Jammy:
+ ```
+ testtools.testresult.real._StringException: Traceback (most recent call last):
+ File
"/home/wesley/Workspace/ubuntu/python-etcd3gw/etcd3gw/tests/test_etcd3gw.py",
line 382, in test_client_locks
+ lock = self.client.lock(id='xyz-%s' % time.clock(), ttl=60)
+ AttributeError: module 'time' has no attribute 'clock'
+ ```
+
+ [ Where problems could occur ]
+
+ * If
+ - A timeout is provided by a caller of Etcd3Client
+ - The client is used to issue a request that routinely takes longer than
the timeout _to respond at all_
+ The request will fail. This is unlikely as the timeout parameter sets the
socket timeout, so a request does not have to complete in order to avoid timing
out (e.g. this doesn't threaten large/long downloads).
+
+ [ Original Description ]
+
There is currently no timeout set in the requests session object, which means
it will wait indefinitely and cause the process to hang if no response is
received.
For more information, see
https://pylint.readthedocs.io/en/latest/user_guide/messages/warning/missing-timeout.html.
Steps to reproduce this Bug:
$ cat >timeout1.py<<EOF
import etcd3gw
client = etcd3gw.Etcd3Client(timeout=1)
resp = client.session.post("https://httpbin.org/delay/10")
print(resp.status_code)
EOF
Expected behavior:
requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='httpbin.org',
port=443): Read timed out. (read timeout=1)
Actual behavior:
$ python3 timeout1.py
200
The issue can be resolved utilizing functools -
https://github.com/psf/requests/issues/2011#issuecomment-637156626.
These are my proposed changes in fixing the timeout issue.
diff --git a/etcd3gw/client.py b/etcd3gw/client.py
index 43690ce..63fb588 100644
--- a/etcd3gw/client.py
+++ b/etcd3gw/client.py
@@ -10,6 +10,7 @@
- # License for the specific language governing permissions and limitations
- # under the License.
+ # License for the specific language governing permissions and limitations
+ # under the License.
+import functools
- import json
- import os
- import queue
+ import json
+ import os
+ import queue
@@ -57,7 +58,10 @@ class Etcd3Client(object):
- self.session = requests.Session()
- if timeout is not None:
- - self.session.timeout = timeout
- + self.session.request = functools.partial(self.session.request,
timeout=timeout)
- + else:
- + self.session.request = functools.partial(self.session.request,
timeout=DEFAULT_TIMEOUT)
+ self.session = requests.Session()
+ if timeout is not None:
+ - self.session.timeout = timeout
+ + self.session.request = functools.partial(self.session.request,
timeout=timeout)
+ + else:
+ + self.session.request = functools.partial(self.session.request,
timeout=DEFAULT_TIMEOUT)
+
- if ca_cert is not None:
- self.session.verify = ca_cert
- if cert_cert is not None and cert_key is not None:
+ if ca_cert is not None:
+ self.session.verify = ca_cert
+ if cert_cert is not None and cert_key is not None:
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2012261
Title:
Timeout not correctly set inside requests session object
To manage notifications about this bug go to:
https://bugs.launchpad.net/python-etcd3gw/+bug/2012261/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs