131 lines
3.0 KiB
Bash
Executable File
131 lines
3.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -u
|
|
|
|
if (( BASH_VERSINFO[0] < 4 || (BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] < 3) )); then
|
|
echo "[ERROR] start-all.sh requires Bash 4.3 or newer." >&2
|
|
exit 1
|
|
fi
|
|
|
|
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
|
|
BACKEND_SCRIPT="$SCRIPT_DIR/start-backend.sh"
|
|
FRONTEND_SCRIPT="$SCRIPT_DIR/start-reactflow.sh"
|
|
|
|
if [[ ! -x "$BACKEND_SCRIPT" ]]; then
|
|
echo "[ERROR] Backend start script is missing or not executable:" >&2
|
|
echo " $BACKEND_SCRIPT" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -x "$FRONTEND_SCRIPT" ]]; then
|
|
echo "[ERROR] Frontend start script is missing or not executable:" >&2
|
|
echo " $FRONTEND_SCRIPT" >&2
|
|
exit 1
|
|
fi
|
|
|
|
BACKEND_PID=""
|
|
FRONTEND_PID=""
|
|
|
|
signal_process_group() {
|
|
local signal="$1"
|
|
local pid="$2"
|
|
|
|
[[ -n "$pid" ]] || return 0
|
|
kill "-$signal" -- "-$pid" 2>/dev/null || kill "-$signal" "$pid" 2>/dev/null || true
|
|
}
|
|
|
|
process_group_is_running() {
|
|
local pid="$1"
|
|
|
|
[[ -n "$pid" ]] && kill -0 -- "-$pid" 2>/dev/null
|
|
}
|
|
|
|
cleanup() {
|
|
local backend_cleared=false
|
|
local force_kill=false
|
|
local frontend_cleared=false
|
|
local launcher_pid=$$
|
|
local timer_pid
|
|
|
|
trap '' INT TERM HUP
|
|
trap - EXIT
|
|
trap 'force_kill=true' ALRM
|
|
|
|
signal_process_group TERM "$BACKEND_PID"
|
|
signal_process_group TERM "$FRONTEND_PID"
|
|
|
|
(
|
|
sleep 5
|
|
kill -ALRM "$launcher_pid" 2>/dev/null || true
|
|
) &
|
|
timer_pid=$!
|
|
|
|
if [[ -n "$BACKEND_PID" ]]; then
|
|
wait "$BACKEND_PID" 2>/dev/null || true
|
|
fi
|
|
if [[ "$force_kill" == false && -n "$FRONTEND_PID" ]]; then
|
|
wait "$FRONTEND_PID" 2>/dev/null || true
|
|
fi
|
|
|
|
while [[ "$force_kill" == false ]]; do
|
|
if [[ "$backend_cleared" == false ]] && ! process_group_is_running "$BACKEND_PID"; then
|
|
backend_cleared=true
|
|
fi
|
|
if [[ "$frontend_cleared" == false ]] && ! process_group_is_running "$FRONTEND_PID"; then
|
|
frontend_cleared=true
|
|
fi
|
|
if [[ "$backend_cleared" == true && "$frontend_cleared" == true ]]; then
|
|
break
|
|
fi
|
|
sleep 0.1
|
|
done
|
|
|
|
kill -KILL "$timer_pid" 2>/dev/null || true
|
|
wait "$timer_pid" 2>/dev/null || true
|
|
|
|
if [[ "$force_kill" == true ]]; then
|
|
if [[ "$backend_cleared" == false ]] && ! process_group_is_running "$BACKEND_PID"; then
|
|
backend_cleared=true
|
|
fi
|
|
if [[ "$frontend_cleared" == false ]] && ! process_group_is_running "$FRONTEND_PID"; then
|
|
frontend_cleared=true
|
|
fi
|
|
if [[ "$backend_cleared" == false ]]; then
|
|
signal_process_group KILL "$BACKEND_PID"
|
|
fi
|
|
if [[ "$frontend_cleared" == false ]]; then
|
|
signal_process_group KILL "$FRONTEND_PID"
|
|
fi
|
|
fi
|
|
|
|
if [[ -n "$BACKEND_PID" ]]; then
|
|
wait "$BACKEND_PID" 2>/dev/null || true
|
|
fi
|
|
if [[ -n "$FRONTEND_PID" ]]; then
|
|
wait "$FRONTEND_PID" 2>/dev/null || true
|
|
fi
|
|
|
|
trap - ALRM
|
|
}
|
|
|
|
trap cleanup EXIT
|
|
trap 'exit 130' INT
|
|
trap 'exit 143' TERM
|
|
trap 'exit 129' HUP
|
|
|
|
echo "Starting FastAPI and ReactFlow..."
|
|
echo "Press Ctrl+C to stop both services."
|
|
echo
|
|
|
|
set -m
|
|
"$BACKEND_SCRIPT" &
|
|
BACKEND_PID=$!
|
|
"$FRONTEND_SCRIPT" &
|
|
FRONTEND_PID=$!
|
|
set +m
|
|
|
|
wait -n
|
|
EXIT_CODE=$?
|
|
|
|
exit "$EXIT_CODE"
|