Skip to content

Commit 7bf4516

Browse files
authored
fix: avoid unintentionally interrupted from subprocess on Windows (#982)
1 parent a341611 commit 7bf4516

File tree

4 files changed

+18
-52
lines changed

4 files changed

+18
-52
lines changed

.github/workflows/_test.yml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,6 @@ jobs:
5555
run: |
5656
${{ matrix.platform.python_exec }} -m mypy python
5757
- name: Python tests
58-
if: ${{ !startsWith(matrix.platform.runner, 'windows') }}
59-
run: |
60-
${{ matrix.platform.python_exec }} -m pytest --capture=no python/cocoindex/tests
61-
- name: Python tests (Windows cmd)
62-
if: ${{ startsWith(matrix.platform.runner, 'windows') }}
63-
shell: cmd # Use `cmd` to run test for Windows, as PowerShell doesn't detect exit code by `os._exit(0)` correctly.
6458
run: |
6559
${{ matrix.platform.python_exec }} -m pytest --capture=no python/cocoindex/tests
6660

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ dependencies = [
1515
"python-dotenv>=1.1.0",
1616
"watchfiles>=1.1.0",
1717
"numpy>=1.23.2",
18+
"psutil>=7.0.0",
1819
]
1920
license = "Apache-2.0"
2021
license-files = ["THIRD_PARTY_NOTICES.html"]

python/cocoindex/subprocess_exec.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -134,18 +134,27 @@ def _start_parent_watchdog(
134134
This runs in a background daemon thread so it never blocks pool work.
135135
"""
136136

137+
import psutil # type: ignore
138+
139+
if parent_pid is None:
140+
parent_pid = os.getppid()
141+
142+
try:
143+
p = psutil.Process(parent_pid)
144+
# Cache create_time to defeat PID reuse.
145+
created = p.create_time()
146+
except psutil.Error:
147+
# Parent already gone or not accessible
148+
os._exit(1)
149+
137150
def _watch() -> None:
138151
while True:
139-
# If PPID changed (parent died and we were reparented), exit.
140-
if os.getppid() != parent_pid:
141-
os._exit(1)
142-
143-
# Best-effort liveness probe in case PPID was reused.
144152
try:
145-
os.kill(parent_pid, 0)
146-
except OSError:
153+
# is_running() + same create_time => same process and still alive
154+
if not (p.is_running() and p.create_time() == created):
155+
os._exit(1)
156+
except psutil.NoSuchProcess:
147157
os._exit(1)
148-
149158
time.sleep(interval_seconds)
150159

151160
threading.Thread(target=_watch, name="parent-watchdog", daemon=True).start()

python/cocoindex/tests/conftest.py

Lines changed: 0 additions & 38 deletions
This file was deleted.

0 commit comments

Comments
 (0)