feat: handle cli processes cleanup when terminal window is closed
This commit is contained in:
parent
079a5528b0
commit
2c8d8e8058
1 changed files with 34 additions and 17 deletions
|
|
@ -180,33 +180,42 @@ def main() -> int:
|
||||||
def signal_handler(signum, frame):
|
def signal_handler(signum, frame):
|
||||||
"""Handle Ctrl+C and other termination signals"""
|
"""Handle Ctrl+C and other termination signals"""
|
||||||
nonlocal spawned_pids, docker_container
|
nonlocal spawned_pids, docker_container
|
||||||
fmt.echo("\nShutting down UI server...")
|
|
||||||
|
try:
|
||||||
|
fmt.echo("\nShutting down UI server...")
|
||||||
|
except (BrokenPipeError, OSError):
|
||||||
|
pass
|
||||||
|
|
||||||
# First, stop Docker container if running
|
# First, stop Docker container if running
|
||||||
if docker_container:
|
if docker_container:
|
||||||
try:
|
try:
|
||||||
fmt.echo(f"Stopping Docker container {docker_container}...")
|
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
["docker", "stop", docker_container],
|
["docker", "stop", docker_container],
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
timeout=10,
|
timeout=10,
|
||||||
check=False,
|
check=False,
|
||||||
)
|
)
|
||||||
if result.returncode == 0:
|
try:
|
||||||
fmt.success(f"✓ Docker container {docker_container} stopped.")
|
if result.returncode == 0:
|
||||||
else:
|
fmt.success(f"✓ Docker container {docker_container} stopped.")
|
||||||
fmt.warning(
|
else:
|
||||||
f"Could not stop container {docker_container}: {result.stderr.decode()}"
|
fmt.warning(
|
||||||
)
|
f"Could not stop container {docker_container}: {result.stderr.decode()}"
|
||||||
|
)
|
||||||
|
except (BrokenPipeError, OSError):
|
||||||
|
pass
|
||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
fmt.warning(
|
try:
|
||||||
f"Timeout stopping container {docker_container}, forcing removal..."
|
fmt.warning(
|
||||||
)
|
f"Timeout stopping container {docker_container}, forcing removal..."
|
||||||
|
)
|
||||||
|
except (BrokenPipeError, OSError):
|
||||||
|
pass
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
["docker", "rm", "-f", docker_container], capture_output=True, check=False
|
["docker", "rm", "-f", docker_container], capture_output=True, check=False
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception:
|
||||||
fmt.warning(f"Could not stop Docker container {docker_container}: {e}")
|
pass
|
||||||
|
|
||||||
# Then, stop regular processes
|
# Then, stop regular processes
|
||||||
for pid in spawned_pids:
|
for pid in spawned_pids:
|
||||||
|
|
@ -215,7 +224,10 @@ def main() -> int:
|
||||||
# Unix-like systems: Use process groups
|
# Unix-like systems: Use process groups
|
||||||
pgid = os.getpgid(pid)
|
pgid = os.getpgid(pid)
|
||||||
os.killpg(pgid, signal.SIGTERM)
|
os.killpg(pgid, signal.SIGTERM)
|
||||||
fmt.success(f"✓ Process group {pgid} (PID {pid}) terminated.")
|
try:
|
||||||
|
fmt.success(f"✓ Process group {pgid} (PID {pid}) terminated.")
|
||||||
|
except (BrokenPipeError, OSError):
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
# Windows: Use taskkill to terminate process and its children
|
# Windows: Use taskkill to terminate process and its children
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
|
|
@ -223,14 +235,19 @@ def main() -> int:
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
check=False,
|
check=False,
|
||||||
)
|
)
|
||||||
fmt.success(f"✓ Process {pid} and its children terminated.")
|
try:
|
||||||
except (OSError, ProcessLookupError, subprocess.SubprocessError) as e:
|
fmt.success(f"✓ Process {pid} and its children terminated.")
|
||||||
fmt.warning(f"Could not terminate process {pid}: {e}")
|
except (BrokenPipeError, OSError):
|
||||||
|
pass
|
||||||
|
except (OSError, ProcessLookupError, subprocess.SubprocessError):
|
||||||
|
pass
|
||||||
|
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
signal.signal(signal.SIGINT, signal_handler) # Ctrl+C
|
signal.signal(signal.SIGINT, signal_handler) # Ctrl+C
|
||||||
signal.signal(signal.SIGTERM, signal_handler) # Termination request
|
signal.signal(signal.SIGTERM, signal_handler) # Termination request
|
||||||
|
if hasattr(signal, "SIGHUP"):
|
||||||
|
signal.signal(signal.SIGHUP, signal_handler)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from cognee import start_ui
|
from cognee import start_ui
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue