From d2b284fe9ef3ede871fa0e0ee4432b1944556701 Mon Sep 17 00:00:00 2001 From: Tzu-ping Chung Date: Tue, 21 Mar 2023 16:56:48 +0800 Subject: [PATCH 1/2] Fix process killing with subprocess API --- airflow/cli/commands/webserver_command.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/airflow/cli/commands/webserver_command.py b/airflow/cli/commands/webserver_command.py index 685cc428891c1..2fcd63f052042 100644 --- a/airflow/cli/commands/webserver_command.py +++ b/airflow/cli/commands/webserver_command.py @@ -425,14 +425,18 @@ def webserver(args): # then have a copy of the app run_args += ["--preload"] - gunicorn_master_proc: psutil.Process | None = None + gunicorn_master_proc: psutil.Process | subprocess.Popen def kill_proc(signum, _): log.info("Received signal: %s. Closing gunicorn.", signum) gunicorn_master_proc.terminate() with suppress(TimeoutError): gunicorn_master_proc.wait(timeout=30) - if gunicorn_master_proc.is_running(): + if isinstance(gunicorn_master_proc, subprocess.Popen): + still_running = gunicorn_master_proc.poll() is not None + else: + still_running = gunicorn_master_proc.is_running() + if still_running: gunicorn_master_proc.kill() sys.exit(0) From a9c2bed6855b83afaefd2b70e8c0549aad2ed724 Mon Sep 17 00:00:00 2001 From: Tzu-ping Chung Date: Tue, 21 Mar 2023 17:03:25 +0800 Subject: [PATCH 2/2] Improve signal handler typing --- airflow/cli/commands/webserver_command.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/airflow/cli/commands/webserver_command.py b/airflow/cli/commands/webserver_command.py index 2fcd63f052042..14fc17558ba7b 100644 --- a/airflow/cli/commands/webserver_command.py +++ b/airflow/cli/commands/webserver_command.py @@ -25,6 +25,7 @@ import sys import textwrap import time +import types from contextlib import suppress from time import sleep from typing import NoReturn @@ -427,7 +428,7 @@ def webserver(args): gunicorn_master_proc: psutil.Process | subprocess.Popen - def kill_proc(signum, _): + def kill_proc(signum: int, frame: types.FrameType | None) -> NoReturn: log.info("Received signal: %s. Closing gunicorn.", signum) gunicorn_master_proc.terminate() with suppress(TimeoutError): @@ -440,7 +441,7 @@ def kill_proc(signum, _): gunicorn_master_proc.kill() sys.exit(0) - def monitor_gunicorn(gunicorn_master_pid: int): + def monitor_gunicorn(gunicorn_master_pid: int) -> NoReturn: # Register signal handlers signal.signal(signal.SIGINT, kill_proc) signal.signal(signal.SIGTERM, kill_proc)