From 0c9b2667902d987c9f8fe8c869a823bc6b121e5d Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 13 Jan 2025 18:44:27 +0530 Subject: [PATCH] fix: Request timeout for gthread workers (#1) * ci: drop unsupported versions * fix: a *dirty* request timeout for gthread workers * fix: drain current futures before exiting * fix: avoid accepting new connections completely * refactor: Just rely on graceful_timeout This has minor side effect of no progress on accepted BUT not "read" reqeusts. But I feel this makes code simpler and less prone to bugs. These time outs should be *rare* and fixed anyway. --- .github/workflows/tox.yml | 7 ------- gunicorn/workers/gthread.py | 9 +++++++++ tox.ini | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 759800eb..36bdeee9 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -21,16 +21,9 @@ jobs: - macos-13 # Not testing Windows, because tests need Unix-only fcntl, grp, pwd, etc. python-version: - # CPython <= 3.7 is EoL since 2023-06-27 - - "3.7" - - "3.8" - - "3.9" - "3.10" - "3.11" - "3.12" - # PyPy <= 3.8 is EoL since 2023-06-16 - - "pypy-3.9" - - "pypy-3.10" include: # Note: potentially "universal2" release # https://github.com/actions/runner-images/issues/9741 diff --git a/gunicorn/workers/gthread.py b/gunicorn/workers/gthread.py index 7a23228c..0d2272f2 100644 --- a/gunicorn/workers/gthread.py +++ b/gunicorn/workers/gthread.py @@ -107,6 +107,7 @@ class ThreadWorker(base.Worker): def _wrap_future(self, fs, conn): fs.conn = conn + fs._request_timeout = time.monotonic() + self.cfg.timeout self.futures.append(fs) fs.add_done_callback(self.finish_request) @@ -230,6 +231,14 @@ class ThreadWorker(base.Worker): # handle keepalive timeouts self.murder_keepalived() + # `gthread` does not implement ANY kind of request timeout, the + # simplest request timeout will kill the entire worker. + current_time = time.monotonic() + for fut in self.futures: + if current_time > fut._request_timeout: + self.alive = False + self.log.error("A request timed out. Exiting.") + self.tpool.shutdown(False) self.poller.close() diff --git a/tox.ini b/tox.ini index 9bf99e1b..b31a6c64 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{37,38,39,310,311,312,py3}, + py{310,311,312,py3}, lint, docs-lint, pycodestyle,