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:
57
start.sh
57
start.sh
@@ -8,7 +8,7 @@
|
|||||||
# ./start.sh --status Show service status
|
# ./start.sh --status Show service status
|
||||||
# ./start.sh --help Show help
|
# ./start.sh --help Show help
|
||||||
|
|
||||||
set -e
|
# Note: We don't use 'set -e' here because stop commands may fail gracefully
|
||||||
|
|
||||||
# Colors
|
# Colors
|
||||||
GREEN='\033[0;32m'
|
GREEN='\033[0;32m'
|
||||||
@@ -181,16 +181,47 @@ start_frontend() {
|
|||||||
fi
|
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() {
|
stop_service() {
|
||||||
local name=$1
|
local name=$1
|
||||||
local pid_file=$2
|
local pid_file=$2
|
||||||
|
local port=$3
|
||||||
|
|
||||||
if is_running "$pid_file"; then
|
if is_running "$pid_file"; then
|
||||||
local pid=$(get_pid "$pid_file")
|
local pid=$(get_pid "$pid_file")
|
||||||
echo -e "${YELLOW}Stopping $name (PID: $pid)...${NC}"
|
echo -e "${YELLOW}Stopping $name (PID: $pid)...${NC}"
|
||||||
|
|
||||||
# Try graceful shutdown first
|
# Kill the entire process tree
|
||||||
kill -TERM "$pid" 2>/dev/null || true
|
kill_process_tree "$pid"
|
||||||
|
|
||||||
# Wait up to 5 seconds
|
# Wait up to 5 seconds
|
||||||
local count=0
|
local count=0
|
||||||
@@ -201,20 +232,28 @@ stop_service() {
|
|||||||
|
|
||||||
# Force kill if still running
|
# Force kill if still running
|
||||||
if is_running "$pid_file"; then
|
if is_running "$pid_file"; then
|
||||||
kill -9 "$pid" 2>/dev/null || true
|
force_kill_process_tree "$pid"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -f "$pid_file"
|
rm -f "$pid_file"
|
||||||
echo -e "${GREEN}$name stopped${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${YELLOW}$name is not running${NC}"
|
|
||||||
fi
|
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() {
|
stop_all() {
|
||||||
echo -e "${YELLOW}Stopping all services...${NC}"
|
echo -e "${YELLOW}Stopping all services...${NC}"
|
||||||
stop_service "Backend" "$BACKEND_PID_FILE"
|
stop_service "Backend" "$BACKEND_PID_FILE" "$BACKEND_PORT"
|
||||||
stop_service "Frontend" "$FRONTEND_PID_FILE"
|
stop_service "Frontend" "$FRONTEND_PID_FILE" "$FRONTEND_PORT"
|
||||||
echo -e "${GREEN}All services stopped${NC}"
|
echo -e "${GREEN}All services stopped${NC}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user