1fanwang commented on PR #70573:
URL: https://github.com/apache/airflow/pull/70573#issuecomment-5101344307

   Thanks for tracking this down, @jason810496. landed on the same RC while 
chasing this:
   
   The detached job keeps the launcher's terminal on fd 0, so the fresh  setsid 
 session leader re-acquires it as its controlling terminal. When the pty hangs 
up, the job gets SIGHUP and dies. Redirecting stdin from  /dev/null  is what 
fully detaches it, exactly as you have it on both the  setsid  and  nohup  
paths.
   
   I reproduced it in a Linux container. The controlling-terminal timing makes 
it intermittent on CI but deterministic in a slower Docker VM, which gives a 
clean before/after.
   
   1. Baseline (current main): the real test fails with the CI assertion, all 5 
reruns exhausted
   
   
   # Linux 6.10.14-linuxkit aarch64
   $ pytest 
test_remote_job.py::TestPosixKillBehaviour::test_kill_terminates_whole_job_tree_under_job_control
 --noconftest
   
           job_pids = subprocess.run(
               ["pgrep", "-f", marker], capture_output=True, text=True, 
check=False
           ).stdout.split()
   >       assert job_pids, "job never started"
   E       AssertionError: job never started
   E       assert []
   
   test_remote_job.py:426: AssertionError
   =========================== short test summary info 
============================
   FAILED 
test_remote_job.py::TestPosixKillBehaviour::test_kill_terminates_whole_job_tree_under_job_control
   ========================== 1 failed, 5 rerun in 0.32s 
==========================
   
   
   
   
   2. Mechanism: the detached job holds the pty as its controlling terminal
   
   
    ps  on the job right before the pty hangup.  pid == sid == pgid  confirms  
setsid(2)  gave it a new session;  tty = pts/0  shows it still holds the 
launcher's pty as its controlling terminal, which is the path the SIGHUP 
travels down:
   
   recorded pid: 31
   ps (pid sid pgid tty) BEFORE hangup:
     31      31      31 pts/0
   job alive AFTER hangup: False
   
   
   
   
   3. With this PR's change: the test passes deterministically, no regression
   
   
   ### flaky test, 20 consecutive runs with the fix:
     RESULT: pass=20 fail=0 / 20
   ### full TestPosixKillBehaviour + wrapper-content tests:
   ........                                                                 
[100%]
   8 passed, 19 deselected in 0.08s
   
   
   
   
   Reproduce
   
   
   # From an apache/airflow checkout. The test skips on macOS, so run it under 
Linux/Docker:
   docker run --rm -v "$PWD:/repo" -w /tmp python:3.10 bash -c '
     apt-get update -qq && apt-get install -y -qq util-linux procps >/dev/null
     pip install -q pytest pytest-rerunfailures
     cp /repo/providers/ssh/src/airflow/providers/ssh/utils/remote_job.py .
     cp /repo/providers/ssh/tests/unit/ssh/utils/test_remote_job.py .
     sed -i "s/from airflow.providers.ssh.utils.remote_job import (/from 
remote_job import (/" test_remote_job.py
     pytest 
test_remote_job.py::TestPosixKillBehaviour::test_kill_terminates_whole_job_tree_under_job_control
 --noconftest'
   
   
   
   
   Dropping the  @pytest.mark.flaky(reruns=5)  marker is the right call too: 
with stdin detached the test passed 20/20 for me, so it no longer needs reruns. 
+1 from me.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to