feat: add process group management to prevent hanging subprocesses
- Add start_new_session=True to subprocess.Popen for better isolation - Use os.killpg() to terminate entire process groups instead of single processes - Import signal module for SIGTERM/SIGKILL handling - This ensures child processes of embedding servers are also cleaned up 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import atexit
|
import atexit
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import signal
|
||||||
import socket
|
import socket
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
@@ -311,6 +312,7 @@ class EmbeddingServerManager:
|
|||||||
cwd=project_root,
|
cwd=project_root,
|
||||||
stdout=None, # Direct to console
|
stdout=None, # Direct to console
|
||||||
stderr=None, # Direct to console
|
stderr=None, # Direct to console
|
||||||
|
start_new_session=True, # Create new process group for better cleanup
|
||||||
)
|
)
|
||||||
self.server_port = port
|
self.server_port = port
|
||||||
logger.info(f"Server process started with PID: {self.server_process.pid}")
|
logger.info(f"Server process started with PID: {self.server_process.pid}")
|
||||||
@@ -352,7 +354,14 @@ class EmbeddingServerManager:
|
|||||||
logger.info(
|
logger.info(
|
||||||
f"Terminating server process (PID: {self.server_process.pid}) for backend {self.backend_module_name}..."
|
f"Terminating server process (PID: {self.server_process.pid}) for backend {self.backend_module_name}..."
|
||||||
)
|
)
|
||||||
self.server_process.terminate()
|
|
||||||
|
# Try terminating the whole process group first
|
||||||
|
try:
|
||||||
|
pgid = os.getpgid(self.server_process.pid)
|
||||||
|
os.killpg(pgid, signal.SIGTERM)
|
||||||
|
except Exception:
|
||||||
|
# Fallback to terminating just the process
|
||||||
|
self.server_process.terminate()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.server_process.wait(timeout=3)
|
self.server_process.wait(timeout=3)
|
||||||
@@ -361,7 +370,13 @@ class EmbeddingServerManager:
|
|||||||
logger.warning(
|
logger.warning(
|
||||||
f"Server process {self.server_process.pid} did not terminate gracefully within 3 seconds, killing it."
|
f"Server process {self.server_process.pid} did not terminate gracefully within 3 seconds, killing it."
|
||||||
)
|
)
|
||||||
self.server_process.kill()
|
# Try killing the whole process group
|
||||||
|
try:
|
||||||
|
pgid = os.getpgid(self.server_process.pid)
|
||||||
|
os.killpg(pgid, signal.SIGKILL)
|
||||||
|
except Exception:
|
||||||
|
# Fallback to killing just the process
|
||||||
|
self.server_process.kill()
|
||||||
try:
|
try:
|
||||||
self.server_process.wait(timeout=2)
|
self.server_process.wait(timeout=2)
|
||||||
logger.info(f"Server process {self.server_process.pid} killed successfully.")
|
logger.info(f"Server process {self.server_process.pid} killed successfully.")
|
||||||
|
|||||||
Reference in New Issue
Block a user