From 68bf182be461abbde7462e340d2915aeb3e7c8e1 Mon Sep 17 00:00:00 2001 From: Kevin Michel Date: Thu, 11 Apr 2024 17:00:29 +0200 Subject: [PATCH] Fix dangling socket causing uvicorn shutdown failure When using urllib3<=1.26.18 with uvicorn<=0.23.2 and python>=3.12, the socket shutdown method of urllib3 combines with the uvicorn server shutdown to leave the server stuck for many seconds: https://github.com/encode/uvicorn/pull/2145 Updating urllib3 or uvicorn (or downgrading Python) fixes the bug, but Fedora 39 shipped Python 3.12 with old urllib3 and uvicorn. Since we (sadly) open a connection just for a single request every time, we can disable the HTTP keep-alive. This allows the server to close the connection earlier, without waiting for the client. This fixes the failing tests/system/test_astacus.py::test_astacus on Fedora 39. --- astacus/common/utils.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/astacus/common/utils.py b/astacus/common/utils.py index f895ddbd..0e17afc4 100644 --- a/astacus/common/utils.py +++ b/astacus/common/utils.py @@ -90,6 +90,13 @@ def http_request(url, *, caller, method="get", timeout=10, ignore_status_code: b # using passwords in urls here. logger.info("request %s %s by %s", method, url, caller) try: + # There is a combination of bugs between urllib3<2 and uvicorn<0.24.0 + # where the abrupt socket shutdown of urllib3 causes the uvicorn server + # to wait for a long time when shutting down, only on Python>=3.12. + # Since we don't use multi-requests sessions, disable Keep-Alive to + # allow the server to shut down the connection on its side as soon as + # it is done replying. + kw["headers"] = {"Connection": "close", **kw.get("headers", {})} r = requests.request(method, url, timeout=timeout, **kw) if r.ok: return r.json()