Skip to content

Fix zombie process accumulation from git operations in cloud environments #1419

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions jupyterlab_git/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import tornado.locks
from jupyter_server.utils import ensure_async
from nbdime import diff_notebooks, merge_notebooks
import signal

from .log import get_logger

Expand Down Expand Up @@ -55,6 +56,36 @@
execution_lock = tornado.locks.Lock()


def sigchld_handler(signum, frame):
"""Handle SIGCHLD to reap zombie processes from git operations.

Git commands often spawn helper processes (git-credential-helper, git-remote-https,
ssh, git-upload-pack, git-receive-pack) that can become zombie processes when the
main git process exits before its children complete.

This is particularly problematic in cloud/container environments where:
- The application runs as PID 1 or under minimal init systems
- Standard init process zombie reaping may be unreliable or slow
- Resource constraints can cause zombie accumulation

This handler automatically reaps any zombie processes to prevent system resource leaks.
"""
while True:
try:
# Reap child processes non-blockingly
pid, status = os.waitpid(-1, os.WNOHANG)
if pid == 0: # No more children to reap
break
get_logger().debug(f"Reaped child process {pid} with status {status}")
except OSError:
# No child processes or other error
break


# Set up SIGCHLD handler for automatic zombie reaping
signal.signal(signal.SIGCHLD, sigchld_handler)


class State(IntEnum):
"""Git repository state."""

Expand Down
Loading