Skip to content

Commit 2744f14

Browse files
authored
Add --timeout-worker-healthcheck setting (#2711)
1 parent 1dfb0bd commit 2744f14

File tree

4 files changed

+15
-1
lines changed

4 files changed

+15
-1
lines changed

docs/settings.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ Using Uvicorn with watchfiles will enable the following options (which are other
7575

7676
* `--workers <int>` - Number of worker processes. Defaults to the `$WEB_CONCURRENCY` environment variable if available, or 1. Not valid with `--reload`.
7777
* `--env-file <path>` - Environment configuration file for the ASGI application. **Default:** *None*.
78+
* `--timeout-worker-healthcheck <int>` - Maximum number of seconds to wait for a worker to respond to a healthcheck. **Default:** *5*.
7879

7980
!!! note
8081
The `--reload` and `--workers` arguments are mutually exclusive. You cannot use both at the same time.

uvicorn/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ def __init__(
214214
timeout_keep_alive: int = 5,
215215
timeout_notify: int = 30,
216216
timeout_graceful_shutdown: int | None = None,
217+
timeout_worker_healthcheck: int = 5,
217218
callback_notify: Callable[..., Awaitable[None]] | None = None,
218219
ssl_keyfile: str | os.PathLike[str] | None = None,
219220
ssl_certfile: str | os.PathLike[str] | None = None,
@@ -258,6 +259,7 @@ def __init__(
258259
self.timeout_keep_alive = timeout_keep_alive
259260
self.timeout_notify = timeout_notify
260261
self.timeout_graceful_shutdown = timeout_graceful_shutdown
262+
self.timeout_worker_healthcheck = timeout_worker_healthcheck
261263
self.callback_notify = callback_notify
262264
self.ssl_keyfile = ssl_keyfile
263265
self.ssl_certfile = ssl_certfile

uvicorn/main.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,13 @@ def print_version(ctx: click.Context, param: click.Parameter, value: bool) -> No
285285
default=None,
286286
help="Maximum number of seconds to wait for graceful shutdown.",
287287
)
288+
@click.option(
289+
"--timeout-worker-healthcheck",
290+
type=int,
291+
default=5,
292+
help="Maximum number of seconds to wait for a worker to respond to a healthcheck.",
293+
show_default=True,
294+
)
288295
@click.option("--ssl-keyfile", type=str, default=None, help="SSL key file", show_default=True)
289296
@click.option(
290297
"--ssl-certfile",
@@ -399,6 +406,7 @@ def main(
399406
limit_max_requests: int,
400407
timeout_keep_alive: int,
401408
timeout_graceful_shutdown: int | None,
409+
timeout_worker_healthcheck: int,
402410
ssl_keyfile: str,
403411
ssl_certfile: str,
404412
ssl_keyfile_password: str,
@@ -448,6 +456,7 @@ def main(
448456
limit_max_requests=limit_max_requests,
449457
timeout_keep_alive=timeout_keep_alive,
450458
timeout_graceful_shutdown=timeout_graceful_shutdown,
459+
timeout_worker_healthcheck=timeout_worker_healthcheck,
451460
ssl_keyfile=ssl_keyfile,
452461
ssl_certfile=ssl_certfile,
453462
ssl_keyfile_password=ssl_keyfile_password,
@@ -500,6 +509,7 @@ def run(
500509
limit_max_requests: int | None = None,
501510
timeout_keep_alive: int = 5,
502511
timeout_graceful_shutdown: int | None = None,
512+
timeout_worker_healthcheck: int = 5,
503513
ssl_keyfile: str | os.PathLike[str] | None = None,
504514
ssl_certfile: str | os.PathLike[str] | None = None,
505515
ssl_keyfile_password: str | None = None,
@@ -552,6 +562,7 @@ def run(
552562
limit_max_requests=limit_max_requests,
553563
timeout_keep_alive=timeout_keep_alive,
554564
timeout_graceful_shutdown=timeout_graceful_shutdown,
565+
timeout_worker_healthcheck=timeout_worker_healthcheck,
555566
ssl_keyfile=ssl_keyfile,
556567
ssl_certfile=ssl_certfile,
557568
ssl_keyfile_password=ssl_keyfile_password,

uvicorn/supervisors/multiprocess.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ def keep_subprocess_alive(self) -> None:
164164
return # parent process is exiting, no need to keep subprocess alive
165165

166166
for idx, process in enumerate(self.processes):
167-
if process.is_alive():
167+
if process.is_alive(timeout=self.config.timeout_worker_healthcheck):
168168
continue
169169

170170
process.kill() # process is hung, kill it

0 commit comments

Comments
 (0)