This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new ac00547512 Replace daemon Thread in dev-mode of breeze start-airflow 
with forking (#31403)
ac00547512 is described below

commit ac00547512f33b1222d699c7857108360d99b233
Author: Jarek Potiuk <[email protected]>
AuthorDate: Fri May 19 11:58:16 2023 +0200

    Replace daemon Thread in dev-mode of breeze start-airflow with forking 
(#31403)
    
    * Replace daemon Thread in dev-mode of breeze start-airflow with forking
    
    When you run the dev mode for Breeze start-airlfow the webpack to
    compile the assets is run in the background and should be stopped
    as soon as the main process leaves. This has been done via daemon
    Thread, however it turns out that when daemon thread gets stopped
    at exit, it is stopped pretty abruptly. Quoting
    
    https://docs.python.org/3/library/threading.html ::
    
    > Note Daemon threads are abruptly stopped at shutdown. Their resources
    (such as open files, database transactions, etc.) may not be released
    properly. If you want your threads to stop gracefully, make them
    non-daemonic and use a suitable signalling mechanism such as an Event.
    
    This also means that if the daemon threds starts a subprocess, the
    thread is killed but the subprocess is not - the subprocess gets
    orphaned and gets adopted by init process and continues running.
    
    Tis PR replaces the mechanism with forking. Instead of running
    thread, it will fork a new process that will run the compilation
    (including starting the subprocess that runs it). It will also
    change group for the started forked process to be the same as
    the new pid, which creates a new process group and register
    an atexit method to send TERM to all the processes belonging to
    that grop, so even if the node process that runs compilation does
    not propagate the TERM signal (it does not) to the webpack processes,
    all the webpack processes share the same process group and get the
    SIGTERM signal.
    
    Fixes: #31384
    
    * Update dev/breeze/src/airflow_breeze/utils/run_utils.py
    
    Co-authored-by: Pierre Jeambrun <[email protected]>
    
    ---------
    
    Co-authored-by: Pierre Jeambrun <[email protected]>
---
 dev/breeze/src/airflow_breeze/utils/run_utils.py | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/dev/breeze/src/airflow_breeze/utils/run_utils.py 
b/dev/breeze/src/airflow_breeze/utils/run_utils.py
index 66bc3e1a40..f29ca43006 100644
--- a/dev/breeze/src/airflow_breeze/utils/run_utils.py
+++ b/dev/breeze/src/airflow_breeze/utils/run_utils.py
@@ -17,17 +17,18 @@
 """Useful tools for running commands."""
 from __future__ import annotations
 
+import atexit
 import contextlib
 import os
 import re
 import shlex
+import signal
 import stat
 import subprocess
 import sys
 from distutils.version import StrictVersion
 from functools import lru_cache
 from pathlib import Path
-from threading import Thread
 from typing import Mapping, Union
 
 from rich.markup import escape
@@ -470,7 +471,15 @@ def run_compile_www_assets(
         f"{WWW_ASSET_OUT_DEV_MODE_FILE if dev else WWW_ASSET_OUT_FILE}\n"
     )
     if run_in_background:
-        thread = Thread(daemon=True, target=_run_compile_internally, 
args=(command_to_execute, dev))
-        thread.start()
+        pid = os.fork()
+        if pid:
+            # Parent process - send signal to process group of the child 
process
+            atexit.register(os.killpg, pid, signal.SIGTERM)
+        else:
+            # Check if we are not a group leader already (We should not be)
+            if os.getpid() != os.getsid(0):
+                # and create a new process group where we are the leader
+                os.setpgid(0, 0)
+            _run_compile_internally(command_to_execute, dev)
     else:
         return _run_compile_internally(command_to_execute, dev)

Reply via email to