fix: properly stop child processes and orphaned services

- Kill entire process tree (parent + children) when stopping
- Add port-based cleanup as fallback for orphaned processes
- Remove 'set -e' to allow graceful failure handling
- Pass port numbers to stop_service for cleanup

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
egg
2025-12-02 18:01:24 +08:00
parent 7916c75768
commit bed473cd30

View File

@@ -8,7 +8,7 @@
# ./start.sh --status Show service status
# ./start.sh --help Show help
set -e
# Note: We don't use 'set -e' here because stop commands may fail gracefully
# Colors
GREEN='\033[0;32m'
@@ -181,16 +181,47 @@ start_frontend() {
fi
}
kill_process_tree() {
local pid=$1
# Kill all child processes first
pkill -TERM -P "$pid" 2>/dev/null || true
# Then kill the parent
kill -TERM "$pid" 2>/dev/null || true
}
force_kill_process_tree() {
local pid=$1
# Force kill all child processes
pkill -9 -P "$pid" 2>/dev/null || true
# Force kill the parent
kill -9 "$pid" 2>/dev/null || true
}
kill_by_port() {
local port=$1
local pids=$(lsof -ti :$port 2>/dev/null)
if [ -n "$pids" ]; then
echo "$pids" | xargs kill -TERM 2>/dev/null || true
sleep 1
# Force kill if still running
pids=$(lsof -ti :$port 2>/dev/null)
if [ -n "$pids" ]; then
echo "$pids" | xargs kill -9 2>/dev/null || true
fi
fi
}
stop_service() {
local name=$1
local pid_file=$2
local port=$3
if is_running "$pid_file"; then
local pid=$(get_pid "$pid_file")
echo -e "${YELLOW}Stopping $name (PID: $pid)...${NC}"
# Try graceful shutdown first
kill -TERM "$pid" 2>/dev/null || true
# Kill the entire process tree
kill_process_tree "$pid"
# Wait up to 5 seconds
local count=0
@@ -201,20 +232,28 @@ stop_service() {
# Force kill if still running
if is_running "$pid_file"; then
kill -9 "$pid" 2>/dev/null || true
force_kill_process_tree "$pid"
fi
rm -f "$pid_file"
echo -e "${GREEN}$name stopped${NC}"
else
echo -e "${YELLOW}$name is not running${NC}"
fi
# Also kill any orphaned processes by port (fallback)
if [ -n "$port" ]; then
local port_pids=$(lsof -ti :$port 2>/dev/null)
if [ -n "$port_pids" ]; then
echo -e "${YELLOW}Cleaning up orphaned processes on port $port...${NC}"
kill_by_port "$port"
fi
fi
echo -e "${GREEN}$name stopped${NC}"
}
stop_all() {
echo -e "${YELLOW}Stopping all services...${NC}"
stop_service "Backend" "$BACKEND_PID_FILE"
stop_service "Frontend" "$FRONTEND_PID_FILE"
stop_service "Backend" "$BACKEND_PID_FILE" "$BACKEND_PORT"
stop_service "Frontend" "$FRONTEND_PID_FILE" "$FRONTEND_PORT"
echo -e "${GREEN}All services stopped${NC}"
}