Skip to content

Commit

Permalink
fix reaper_thread() check to handle docker containers
Browse files Browse the repository at this point in the history
  • Loading branch information
karmacoma-eth committed Nov 13, 2024
1 parent 3c1be80 commit 21f29b6
Showing 1 changed file with 26 additions and 13 deletions.
39 changes: 26 additions & 13 deletions src/jsi/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,34 +147,47 @@ def cleanup():
atexit.register(cleanup)


def monitor_parent():
"""
Monitor the parent process and exit if it dies or changes.
def is_in_container() -> bool:
"""Check if we're running inside a container."""

Caveats:
- only works on POSIX systems
- only works if called early enough (before the original parent process exits)
"""
if os.path.exists('/.dockerenv'):
return True
if os.path.exists('/run/.containerenv'):
return True

proc1_cgroup = '/proc/1/cgroup'
if os.path.exists(proc1_cgroup):
with open(proc1_cgroup) as f:
return any(
'docker' in line or 'container' in line
for line in f.readlines()
)

return False


def reaper_thread():
"""Monitor the parent process and exit if it dies or changes."""
parent_pid = os.getppid()

# Skip PID 1 check if we're running in a container
# (when running interactively, the parent shell can have PID 1)
skip_pid1 = is_in_container()

def check_parent():
while True:
try:
current_ppid = os.getppid()

# if parent PID changed (original parent died), we exit
if current_ppid != parent_pid or current_ppid == 1:
if current_ppid != parent_pid and (not skip_pid1 or current_ppid != 1):
stderr.print("parent process died, exiting...")
os.kill(os.getpid(), signal.SIGTERM)
break
time.sleep(1) # check every second
time.sleep(1)
except ProcessLookupError:
# if we can't check parent PID, assume parent died
os.kill(os.getpid(), signal.SIGTERM)
break

# Start monitoring in background thread
monitor_thread = threading.Thread(target=check_parent, daemon=True)
monitor_thread.start()

Expand Down Expand Up @@ -303,7 +316,7 @@ def main(args: list[str] | None = None) -> int:
global stderr

# kick off the parent monitor in the background as early as possible
monitor_parent()
reaper_thread()

if args is None:
args = sys.argv[1:]
Expand Down

0 comments on commit 21f29b6

Please sign in to comment.